Merge remote-tracking branch 'origin/GP-3329-dragonmacher-search-text-hl-bug--SQUASHED'

This commit is contained in:
Ryan Kurtz
2023-04-21 12:45:48 -04:00
130 changed files with 1096 additions and 919 deletions
@@ -21,7 +21,7 @@ import docking.widgets.fieldpanel.field.AttributedString;
import docking.widgets.fieldpanel.field.TextFieldElement; import docking.widgets.fieldpanel.field.TextFieldElement;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GColor; import generic.theme.GColor;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@@ -50,14 +50,14 @@ public class TaintFieldFactory extends FieldFactory {
super(FIELD_NAME); super(FIELD_NAME);
} }
protected TaintFieldFactory(FieldFormatModel formatModel, HighlightProvider highlightProvider, protected TaintFieldFactory(FieldFormatModel formatModel, ListingHighlightProvider highlightProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, formatModel, highlightProvider, displayOptions, fieldOptions); super(FIELD_NAME, formatModel, highlightProvider, displayOptions, fieldOptions);
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, public FieldFactory newInstance(FieldFormatModel formatModel,
HighlightProvider highlightProvider, ToolOptions displayOptions, ListingHighlightProvider highlightProvider, ToolOptions displayOptions,
ToolOptions fieldOptions) { ToolOptions fieldOptions) {
return new TaintFieldFactory(formatModel, highlightProvider, displayOptions, fieldOptions); return new TaintFieldFactory(formatModel, highlightProvider, displayOptions, fieldOptions);
} }
@@ -23,7 +23,7 @@ import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GColor; import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors.Messages; import generic.theme.GThemeDefaults.Colors.Messages;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@@ -61,7 +61,7 @@ public class ExternalDisassemblyFieldFactory extends FieldFactory {
super(FIELD_NAME); super(FIELD_NAME);
} }
private ExternalDisassemblyFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private ExternalDisassemblyFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@@ -96,7 +96,7 @@ public class ExternalDisassemblyFieldFactory extends FieldFactory {
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, public FieldFactory newInstance(FieldFormatModel formatModel,
HighlightProvider highlightProvider, ToolOptions options, ToolOptions fieldOptions) { ListingHighlightProvider highlightProvider, ToolOptions options, ToolOptions fieldOptions) {
return new ExternalDisassemblyFieldFactory(formatModel, highlightProvider, options, return new ExternalDisassemblyFieldFactory(formatModel, highlightProvider, options,
fieldOptions); fieldOptions);
} }
@@ -21,7 +21,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GColor; import generic.theme.GColor;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
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;
@@ -52,7 +52,7 @@ public class EntropyFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private EntropyFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private EntropyFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@@ -154,7 +154,7 @@ public class EntropyFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel myModel, HighlightProvider myHlProvider, public FieldFactory newInstance(FieldFormatModel myModel, ListingHighlightProvider myHlProvider,
ToolOptions displayOptions1, ToolOptions fieldOptions) { ToolOptions displayOptions1, ToolOptions fieldOptions) {
return new EntropyFieldFactory(myModel, myHlProvider, displayOptions1, fieldOptions); return new EntropyFieldFactory(myModel, myHlProvider, displayOptions1, fieldOptions);
} }
@@ -29,7 +29,7 @@ import ghidra.app.merge.tool.ListingMergePanelPlugin;
import ghidra.app.merge.tree.ProgramTreeMergeManager; import ghidra.app.merge.tree.ProgramTreeMergeManager;
import ghidra.app.nav.*; import ghidra.app.nav.*;
import ghidra.app.plugin.core.navigation.GoToAddressLabelPlugin; import ghidra.app.plugin.core.navigation.GoToAddressLabelPlugin;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.util.FieldNavigator; import ghidra.app.util.viewer.util.FieldNavigator;
import ghidra.framework.model.UndoableDomainObject; import ghidra.framework.model.UndoableDomainObject;
import ghidra.framework.plugintool.ModalPluginTool; import ghidra.framework.plugintool.ModalPluginTool;
@@ -516,12 +516,12 @@ class MergeNavigatable implements Navigatable {
} }
@Override @Override
public void removeHighlightProvider(HighlightProvider highlightProvider, Program program) { public void removeHighlightProvider(ListingHighlightProvider highlightProvider, Program program) {
// currently unsupported // currently unsupported
} }
@Override @Override
public void setHighlightProvider(HighlightProvider highlightProvider, Program program) { public void setHighlightProvider(ListingHighlightProvider highlightProvider, Program program) {
// currently unsupported // currently unsupported
} }
@@ -17,7 +17,7 @@ package ghidra.app.nav;
import javax.swing.Icon; import javax.swing.Icon;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
@@ -185,7 +185,7 @@ public interface Navigatable {
* @param highlightProvider the provider * @param highlightProvider the provider
* @param program the program * @param program the program
*/ */
public void setHighlightProvider(HighlightProvider highlightProvider, Program program); public void setHighlightProvider(ListingHighlightProvider highlightProvider, Program program);
/** /**
* Removes the given highlight provider for the given program * Removes the given highlight provider for the given program
@@ -193,5 +193,5 @@ public interface Navigatable {
* @param highlightProvider the provider * @param highlightProvider the provider
* @param program the program * @param program the program
*/ */
public void removeHighlightProvider(HighlightProvider highlightProvider, Program program); public void removeHighlightProvider(ListingHighlightProvider highlightProvider, Program program);
} }
@@ -38,7 +38,7 @@ import ghidra.app.events.ProgramSelectionPluginEvent;
import ghidra.app.nav.Navigatable; import ghidra.app.nav.Navigatable;
import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService; import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.ProgramDropProvider; import ghidra.app.util.ProgramDropProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.format.*; import ghidra.app.util.viewer.format.*;
@@ -322,13 +322,13 @@ public abstract class AbstractCodeBrowserPlugin<P extends CodeViewerProvider> ex
} }
@Override @Override
public void removeHighlightProvider(HighlightProvider highlightProvider, public void removeHighlightProvider(ListingHighlightProvider highlightProvider,
Program highlightProgram) { Program highlightProgram) {
connectedProvider.removeHighlightProvider(highlightProvider, highlightProgram); connectedProvider.removeHighlightProvider(highlightProvider, highlightProgram);
} }
@Override @Override
public void setHighlightProvider(HighlightProvider highlightProvider, public void setHighlightProvider(ListingHighlightProvider highlightProvider,
Program highlightProgram) { Program highlightProgram) {
connectedProvider.setHighlightProvider(highlightProvider, highlightProgram); connectedProvider.setHighlightProvider(highlightProvider, highlightProgram);
} }
@@ -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.
@@ -44,7 +44,7 @@ import ghidra.app.plugin.core.codebrowser.actions.*;
import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService; import ghidra.app.plugin.core.codebrowser.hover.ListingHoverService;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.util.*; import ghidra.app.util.*;
import ghidra.app.util.viewer.field.FieldFactory; import ghidra.app.util.viewer.field.ListingField;
import ghidra.app.util.viewer.format.*; import ghidra.app.util.viewer.format.*;
import ghidra.app.util.viewer.listingpanel.*; import ghidra.app.util.viewer.listingpanel.*;
import ghidra.app.util.viewer.multilisting.MultiListingLayoutModel; import ghidra.app.util.viewer.multilisting.MultiListingLayoutModel;
@@ -79,7 +79,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
private static final String DIVIDER_LOCATION = "DividerLocation"; private static final String DIVIDER_LOCATION = "DividerLocation";
private ImageIcon navigatableIcon; private ImageIcon navigatableIcon;
private Map<Program, HighlightProvider> programHighlighterMap = new HashMap<>(); private Map<Program, ListingHighlightProvider> programHighlighterMap = new HashMap<>();
private ProgramHighlighterProvider highlighterAdapter; private ProgramHighlighterProvider highlighterAdapter;
private ListingPanel listingPanel; private ListingPanel listingPanel;
@@ -144,7 +144,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
listingPanel = new ListingPanel(formatMgr); listingPanel = new ListingPanel(formatMgr);
listingPanel.enablePropertyBasedColorModel(true); listingPanel.enablePropertyBasedColorModel(true);
decorationPanel = new ListingPanelContainer(listingPanel, isConnected); decorationPanel = new ListingPanelContainer(listingPanel, isConnected);
ListingHighlightProvider listingHighlighter = ListingMiddleMouseHighlightProvider listingHighlighter =
createListingHighlighter(listingPanel, tool, decorationPanel); createListingHighlighter(listingPanel, tool, decorationPanel);
highlighterAdapter = new ProgramHighlighterProvider(listingHighlighter); highlighterAdapter = new ProgramHighlighterProvider(listingHighlighter);
listingPanel.addHighlightProvider(highlighterAdapter); listingPanel.addHighlightProvider(highlighterAdapter);
@@ -194,10 +194,10 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
return false; return false;
} }
private ListingHighlightProvider createListingHighlighter(ListingPanel panel, private ListingMiddleMouseHighlightProvider createListingHighlighter(ListingPanel panel,
PluginTool pluginTool, Component repaintComponent) { PluginTool pluginTool, Component repaintComponent) {
ListingHighlightProvider listingHighlighter = ListingMiddleMouseHighlightProvider listingHighlighter =
new ListingHighlightProvider(pluginTool, repaintComponent); new ListingMiddleMouseHighlightProvider(pluginTool, repaintComponent);
panel.addButtonPressedListener(listingHighlighter); panel.addButtonPressedListener(listingHighlighter);
return listingHighlighter; return listingHighlighter;
} }
@@ -398,14 +398,14 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
} }
@Override @Override
public void removeHighlightProvider(HighlightProvider highlightProvider, public void removeHighlightProvider(ListingHighlightProvider highlightProvider,
Program highlightProgram) { Program highlightProgram) {
programHighlighterMap.remove(highlightProgram); programHighlighterMap.remove(highlightProgram);
updateHighlightProvider(); updateHighlightProvider();
} }
@Override @Override
public void setHighlightProvider(HighlightProvider highlightProvider, public void setHighlightProvider(ListingHighlightProvider highlightProvider,
Program highlightProgram) { Program highlightProgram) {
programHighlighterMap.put(highlightProgram, highlightProvider); programHighlighterMap.put(highlightProgram, highlightProvider);
updateHighlightProvider(); updateHighlightProvider();
@@ -1105,23 +1105,23 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
* A class that allows clients to install transient highlighters while keeping the middle-mouse * A class that allows clients to install transient highlighters while keeping the middle-mouse
* highlighting on at the same time. * highlighting on at the same time.
*/ */
private class ProgramHighlighterProvider implements HighlightProvider { private class ProgramHighlighterProvider implements ListingHighlightProvider {
private final ListingHighlightProvider listingHighlighter; private final ListingMiddleMouseHighlightProvider listingHighlighter;
ProgramHighlighterProvider(ListingHighlightProvider listingHighlighter) { ProgramHighlighterProvider(ListingMiddleMouseHighlightProvider listingHighlighter) {
this.listingHighlighter = listingHighlighter; this.listingHighlighter = listingHighlighter;
} }
@Override @Override
public Highlight[] getHighlights(String text, Object obj, public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass, int cursorTextOffset) {
List<Highlight> list = new ArrayList<>(); List<Highlight> list = new ArrayList<>();
HighlightProvider currentExternalHighligter = programHighlighterMap.get(program); ListingHighlightProvider currentExternalHighligter =
programHighlighterMap.get(program);
if (currentExternalHighligter != null) { if (currentExternalHighligter != null) {
Highlight[] highlights = currentExternalHighligter.getHighlights(text, obj, Highlight[] highlights = currentExternalHighligter.createHighlights(text, field,
fieldFactoryClass, cursorTextOffset); cursorTextOffset);
for (Highlight highlight : highlights) { for (Highlight highlight : highlights) {
list.add(highlight); list.add(highlight);
} }
@@ -1130,7 +1130,7 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
// always call the listing highlighter last so the middle-mouse highlight will always // always call the listing highlighter last so the middle-mouse highlight will always
// be on top of other highlights // be on top of other highlights
Highlight[] highlights = Highlight[] highlights =
listingHighlighter.getHighlights(text, obj, fieldFactoryClass, cursorTextOffset); listingHighlighter.createHighlights(text, field, cursorTextOffset);
for (Highlight highlight : highlights) { for (Highlight highlight : highlights) {
list.add(highlight); list.add(highlight);
} }
@@ -34,8 +34,9 @@ import ghidra.GhidraOptions;
import ghidra.GhidraOptions.CURSOR_MOUSE_BUTTON_NAMES; import ghidra.GhidraOptions.CURSOR_MOUSE_BUTTON_NAMES;
import ghidra.app.plugin.processors.generic.PcodeFieldFactory; import ghidra.app.plugin.processors.generic.PcodeFieldFactory;
import ghidra.app.services.ButtonPressedListener; import ghidra.app.services.ButtonPressedListener;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.OptionsChangeListener; import ghidra.framework.options.OptionsChangeListener;
import ghidra.framework.options.ToolOptions; import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
@@ -50,8 +51,8 @@ import ghidra.program.util.*;
import ghidra.util.*; import ghidra.util.*;
import ghidra.util.datastruct.Stack; import ghidra.util.datastruct.Stack;
public class ListingHighlightProvider public class ListingMiddleMouseHighlightProvider
implements ButtonPressedListener, OptionsChangeListener, HighlightProvider { implements ButtonPressedListener, OptionsChangeListener, ListingHighlightProvider {
//@formatter:off //@formatter:off
private static final GColor DEFAULT_HIGHLIGHT_COLOR = new GColor("color.bg.listing.highlighter.default"); private static final GColor DEFAULT_HIGHLIGHT_COLOR = new GColor("color.bg.listing.highlighter.default");
private static final GColor DEFAULT_SCOPED_READ_COLOR = new GColor("color.bg.listing.highlighter.scoped.read"); private static final GColor DEFAULT_SCOPED_READ_COLOR = new GColor("color.bg.listing.highlighter.scoped.read");
@@ -87,7 +88,7 @@ public class ListingHighlightProvider
private final Component repaintComponent; private final Component repaintComponent;
private final PluginTool tool; private final PluginTool tool;
public ListingHighlightProvider(PluginTool tool, Component repaintComponent) { public ListingMiddleMouseHighlightProvider(PluginTool tool, Component repaintComponent) {
this.tool = tool; this.tool = tool;
this.repaintComponent = repaintComponent; this.repaintComponent = repaintComponent;
@@ -102,8 +103,11 @@ public class ListingHighlightProvider
} }
@Override @Override
public Highlight[] getHighlights(String text, Object obj, public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass = field.getFieldFactory().getClass();
ProxyObj<?> proxy = field.getProxy();
Object obj = proxy.getObject();
if (scopeRegisterHighlight && scope != null) { if (scopeRegisterHighlight && scope != null) {
if (fieldFactoryClass == VariableNameFieldFactory.class || if (fieldFactoryClass == VariableNameFieldFactory.class ||
fieldFactoryClass == VariableLocFieldFactory.class) { fieldFactoryClass == VariableLocFieldFactory.class) {
@@ -22,7 +22,7 @@ import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GColor; import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors; import generic.theme.GThemeDefaults.Colors;
import ghidra.app.cmd.function.CallDepthChangeInfo; import ghidra.app.cmd.function.CallDepthChangeInfo;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@@ -44,13 +44,13 @@ public class StackDepthFieldFactory extends FieldFactory {
super(FIELD_NAME); super(FIELD_NAME);
} }
private StackDepthFieldFactory(FieldFormatModel model, HighlightProvider hsProvider, private StackDepthFieldFactory(FieldFormatModel model, ListingHighlightProvider hsProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions);
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel newModel, HighlightProvider highlightProvider, public FieldFactory newInstance(FieldFormatModel newModel, ListingHighlightProvider highlightProvider,
ToolOptions toolDisplayOptions, ToolOptions fieldOptions) { ToolOptions toolDisplayOptions, ToolOptions fieldOptions) {
return new StackDepthFieldFactory(newModel, highlightProvider, toolDisplayOptions, return new StackDepthFieldFactory(newModel, highlightProvider, toolDisplayOptions,
fieldOptions); fieldOptions);
@@ -24,7 +24,7 @@ import ghidra.app.nav.*;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.ProgramPlugin; import ghidra.app.plugin.ProgramPlugin;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.PluginConstants; import ghidra.app.util.PluginConstants;
import ghidra.app.util.navigation.GoToServiceImpl; import ghidra.app.util.navigation.GoToServiceImpl;
import ghidra.app.util.query.TableService; import ghidra.app.util.query.TableService;
@@ -225,7 +225,7 @@ public final class GoToServicePlugin extends ProgramPlugin {
} }
@Override @Override
public void removeHighlightProvider(HighlightProvider highlightProvider, Program program) { public void removeHighlightProvider(ListingHighlightProvider highlightProvider, Program program) {
CodeViewerService service = tool.getService(CodeViewerService.class); CodeViewerService service = tool.getService(CodeViewerService.class);
if (service != null) { if (service != null) {
service.removeHighlightProvider(highlightProvider, program); service.removeHighlightProvider(highlightProvider, program);
@@ -233,7 +233,7 @@ public final class GoToServicePlugin extends ProgramPlugin {
} }
@Override @Override
public void setHighlightProvider(HighlightProvider highlightProvider, Program program) { public void setHighlightProvider(ListingHighlightProvider highlightProvider, Program program) {
CodeViewerService service = tool.getService(CodeViewerService.class); CodeViewerService service = tool.getService(CodeViewerService.class);
if (service != null) { if (service != null) {
service.setHighlightProvider(highlightProvider, program); service.setHighlightProvider(highlightProvider, program);
@@ -22,8 +22,9 @@ import generic.theme.GColor;
import ghidra.GhidraOptions; import ghidra.GhidraOptions;
import ghidra.app.nav.Navigatable; import ghidra.app.nav.Navigatable;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.FieldFactory; import ghidra.app.util.viewer.field.ListingField;
import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.OptionsChangeListener; import ghidra.framework.options.OptionsChangeListener;
import ghidra.framework.options.ToolOptions; import ghidra.framework.options.ToolOptions;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
@@ -51,7 +52,7 @@ class LocationReferencesHighlighter {
private LocationReferencesProvider provider; private LocationReferencesProvider provider;
private LocationReferencesPlugin locationReferencesPlugin; private LocationReferencesPlugin locationReferencesPlugin;
private HighlightProvider highlightProvider; private ListingHighlightProvider highlightProvider;
private MarkerRemover markerRemover; private MarkerRemover markerRemover;
private Color highlightColor; private Color highlightColor;
private OptionsChangeListener optionsListener = (options, name, oldValue, newValue) -> { private OptionsChangeListener optionsListener = (options, name, oldValue, newValue) -> {
@@ -211,19 +212,20 @@ class LocationReferencesHighlighter {
// Inner Classes // Inner Classes
//================================================================================================== //==================================================================================================
private class LocationReferencesHighlightProvider implements HighlightProvider { private class LocationReferencesHighlightProvider implements ListingHighlightProvider {
private final Highlight[] NO_HIGHLIGHTS = new Highlight[0]; private final Highlight[] NO_HIGHLIGHTS = new Highlight[0];
// for the Class parameter
@Override @Override
public Highlight[] getHighlights(String text, Object obj, public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass, int cursorTextOffset) {
if (text == null) { if (text == null) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
LocationDescriptor locationDescriptor = provider.getLocationDescriptor(); LocationDescriptor locationDescriptor = provider.getLocationDescriptor();
return locationDescriptor.getHighlights(text, obj, fieldFactoryClass, highlightColor); ProxyObj<?> proxy = field.getProxy();
Object obj = proxy.getObject();
return locationDescriptor.getHighlights(text, obj, field.getFieldFactory().getClass(),
highlightColor);
} }
} }
@@ -40,8 +40,8 @@ import ghidra.app.plugin.core.table.TableComponentProvider;
import ghidra.app.services.*; import ghidra.app.services.*;
import ghidra.app.util.*; import ghidra.app.util.*;
import ghidra.app.util.query.TableService; import ghidra.app.util.query.TableService;
import ghidra.app.util.viewer.field.BytesFieldFactory; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.field.FieldFactory; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.model.DomainObject; import ghidra.framework.model.DomainObject;
import ghidra.framework.options.*; import ghidra.framework.options.*;
import ghidra.framework.plugintool.*; import ghidra.framework.plugintool.*;
@@ -83,8 +83,6 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
/** Constant for read/writeConfig() for dialog options */ /** Constant for read/writeConfig() for dialog options */
private static final String SHOW_ADVANCED_OPTIONS = "Show Advanced Options"; private static final String SHOW_ADVANCED_OPTIONS = "Show Advanced Options";
final static Highlight[] NO_HIGHLIGHTS = new Highlight[0];
private static final int MAX_PRE_POPULTATE_BYTE_COUNT = 20; private static final int MAX_PRE_POPULTATE_BYTE_COUNT = 20;
private DockingAction searchAction; private DockingAction searchAction;
@@ -334,7 +332,6 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
@Override @Override
public void setSearchText(String maskedString) { public void setSearchText(String maskedString) {
//sets the search value to a bit string provided by the MnemonicSearchPlugin
searchDialog.setSearchText(maskedString); searchDialog.setSearchText(maskedString);
} }
@@ -613,7 +610,7 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
} }
private abstract class SearchResultsHighlighter private abstract class SearchResultsHighlighter
implements HighlightProvider, ComponentProviderActivationListener { implements ListingHighlightProvider, ComponentProviderActivationListener {
private TableComponentProvider<MemSearchResult> provider; private TableComponentProvider<MemSearchResult> provider;
private Program highlightProgram; private Program highlightProgram;
@@ -688,16 +685,20 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
} }
@Override @Override
public Highlight[] getHighlights(String text, Object obj, public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass, int cursorTextOffset) {
Program program = navigatable != null ? navigatable.getProgram() : null; Program program = navigatable != null ? navigatable.getProgram() : null;
Class<? extends FieldFactory> fieldFactoryClass = field.getFieldFactory().getClass();
if (fieldFactoryClass != BytesFieldFactory.class) { if (fieldFactoryClass != BytesFieldFactory.class) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
if (checkRemoveHighlights()) { if (checkRemoveHighlights()) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
if (!(obj instanceof CodeUnit)) {
ProxyObj<?> proxy = field.getProxy();
Object obj = proxy.getObject();
if (!(obj instanceof CodeUnit cu)) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
if (!doHighlight) { if (!doHighlight) {
@@ -708,7 +709,6 @@ public class MemSearchPlugin extends Plugin implements OptionsChangeListener,
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
CodeUnit cu = (CodeUnit) obj;
Address minAddr = cu.getMinAddress(); Address minAddr = cu.getMinAddress();
Address maxAddr = cu.getMaxAddress(); Address maxAddr = cu.getMaxAddress();
List<MemSearchResult> results = getAddressesFoundInRange(minAddr, maxAddr); List<MemSearchResult> results = getAddressesFoundInRange(minAddr, maxAddr);
@@ -16,6 +16,7 @@
package ghidra.app.plugin.core.searchtext; package ghidra.app.plugin.core.searchtext;
import ghidra.GhidraOptions; import ghidra.GhidraOptions;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.app.util.PluginConstants; import ghidra.app.util.PluginConstants;
import ghidra.app.util.query.ProgramLocationPreviewTableModel; import ghidra.app.util.query.ProgramLocationPreviewTableModel;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
@@ -58,11 +59,11 @@ public abstract class AbstractSearchTableModel extends ProgramLocationPreviewTab
throws CancelledException { throws CancelledException {
Searcher searcher = getSearcher(tool, monitor); Searcher searcher = getSearcher(tool, monitor);
monitor.checkCanceled(); monitor.checkCanceled();
ProgramLocation loc = searcher.search(); TextSearchResult result = searcher.search();
while (loc != null && accumulator.size() < searchLimit) { while (result != null && accumulator.size() < searchLimit) {
accumulator.add(loc); accumulator.add(result.programLocation());
monitor.checkCanceled(); monitor.checkCanceled();
loc = searcher.search(); result = searcher.search();
} }
} }
@@ -63,8 +63,8 @@ class ListingDisplaySearcher implements Searcher {
private AddressSetView searchAddresses; private AddressSetView searchAddresses;
private TaskMonitor monitor; private TaskMonitor monitor;
private List<ProgramLocation> locationList; private List<TextSearchResult> results;
private ListIterator<ProgramLocation> locationIterator; private ListIterator<TextSearchResult> locationIterator;
private ProgramLocation startLocation; private ProgramLocation startLocation;
private int startIndex; private int startIndex;
@@ -103,8 +103,8 @@ class ListingDisplaySearcher implements Searcher {
searchPattern = searchPattern =
UserSearchUtils.createSearchPattern(options.getText(), options.isCaseSensitive()); UserSearchUtils.createSearchPattern(options.getText(), options.isCaseSensitive());
locationList = new ArrayList<>(); results = new ArrayList<>();
locationIterator = locationList.listIterator(); locationIterator = results.listIterator();
CodeViewerService service = tool.getService(CodeViewerService.class); CodeViewerService service = tool.getService(CodeViewerService.class);
listingModel = service.getListingModel(); listingModel = service.getListingModel();
@@ -175,34 +175,34 @@ class ListingDisplaySearcher implements Searcher {
return iterators.toArray(new AddressIterator[iterators.size()]); return iterators.toArray(new AddressIterator[iterators.size()]);
} }
ProgramLocation next() { TextSearchResult next() {
if (locationList.size() == 0) { if (results.size() == 0) {
findNext(); findNext();
} }
boolean isForward = options.isForward(); boolean isForward = options.isForward();
if (isForward && locationIterator.hasNext()) { if (isForward && locationIterator.hasNext()) {
ProgramLocation loc = locationIterator.next(); TextSearchResult result = locationIterator.next();
if (!locationIterator.hasNext()) { if (!locationIterator.hasNext()) {
locationList.clear(); results.clear();
locationIterator = locationList.listIterator(); locationIterator = results.listIterator();
} }
return loc; return result;
} }
if (!isForward && locationIterator.hasPrevious()) { if (!isForward && locationIterator.hasPrevious()) {
ProgramLocation loc = locationIterator.previous(); TextSearchResult result = locationIterator.previous();
if (!locationIterator.hasPrevious()) { if (!locationIterator.hasPrevious()) {
locationList.clear(); results.clear();
locationIterator = locationList.listIterator(); locationIterator = results.listIterator();
} }
return loc; return result;
} }
return null; return null;
} }
boolean hasNext() { boolean hasNext() {
if (locationList.size() == 0) { if (results.size() == 0) {
findNext(); findNext();
} }
return options.isForward() ? locationIterator.hasNext() : locationIterator.hasPrevious(); return options.isForward() ? locationIterator.hasNext() : locationIterator.hasPrevious();
@@ -214,7 +214,7 @@ class ListingDisplaySearcher implements Searcher {
} }
@Override @Override
public ProgramLocation search() { public TextSearchResult search() {
try { try {
if (hasNext()) { if (hasNext()) {
return next(); return next();
@@ -245,7 +245,7 @@ class ListingDisplaySearcher implements Searcher {
private void findNext() { private void findNext() {
if (currentLayout != null) { if (currentLayout != null) {
findNextMatch(); findNextMatch();
if (locationList.size() > 0) { if (results.size() > 0) {
return; return;
} }
} }
@@ -256,7 +256,7 @@ class ListingDisplaySearcher implements Searcher {
currentCodeUnit = null; currentCodeUnit = null;
Listing listing = program.getListing(); Listing listing = program.getListing();
while (!monitor.isCancelled() && currentLayout == null && addressIterator.hasNext() && while (!monitor.isCancelled() && currentLayout == null && addressIterator.hasNext() &&
locationList.size() == 0) { results.size() == 0) {
currentAddress = addressIterator.next(); currentAddress = addressIterator.next();
monitor.setMessage("Checking address " + currentAddress); monitor.setMessage("Checking address " + currentAddress);
@@ -287,14 +287,14 @@ class ListingDisplaySearcher implements Searcher {
} }
if (options.isForward()) { if (options.isForward()) {
while (!monitor.isCancelled() && locationList.size() == 0 && while (!monitor.isCancelled() && results.size() == 0 &&
currentLayout != null && currentFieldIndex < currentLayout.getNumFields()) { currentLayout != null && currentFieldIndex < currentLayout.getNumFields()) {
findNextMatch(); findNextMatch();
} }
} }
else { else {
currentFieldIndex = currentLayout.getNumFields() - 1; currentFieldIndex = currentLayout.getNumFields() - 1;
while (!monitor.isCancelled() && locationList.size() == 0 && while (!monitor.isCancelled() && results.size() == 0 &&
currentLayout != null && currentFieldIndex >= 0) { currentLayout != null && currentFieldIndex >= 0) {
findNextMatch(); findNextMatch();
} }
@@ -372,7 +372,7 @@ class ListingDisplaySearcher implements Searcher {
findLocations(field); findLocations(field);
} }
if (locationList.size() > 0) { if (results.size() > 0) {
// we found a match! // we found a match!
return fieldCount; return fieldCount;
} }
@@ -529,7 +529,9 @@ class ListingDisplaySearcher implements Searcher {
if (index == mnemonicLength) { if (index == mnemonicLength) {
col++; col++;
} }
locationList.add(fieldFactory.getProgramLocation(rc.row(), col, mnemonicField));
ProgramLocation loc = fieldFactory.getProgramLocation(rc.row(), col, mnemonicField);
results.add(new TextSearchResult(loc, index));
} }
adjustIterator(); adjustIterator();
@@ -559,8 +561,8 @@ class ListingDisplaySearcher implements Searcher {
RowColLocation rc = field.textOffsetToScreenLocation(index); RowColLocation rc = field.textOffsetToScreenLocation(index);
FieldFactory fieldFactory = field.getFieldFactory(); FieldFactory fieldFactory = field.getFieldFactory();
ProgramLocation loc = fieldFactory.getProgramLocation(rc.row(), rc.col(), field); ProgramLocation loc = fieldFactory.getProgramLocation(rc.row(), rc.col(), field);
if ((loc != null) && !isSameLocation(loc)) { // loc will be null if field is clipped. if ((loc != null) && !isSameLocation(loc)) { // loc will be null if field is clipped.
locationList.add(loc); results.add(new TextSearchResult(loc, index));
} }
} }
@@ -570,7 +572,7 @@ class ListingDisplaySearcher implements Searcher {
} }
private void adjustIterator() { private void adjustIterator() {
locationIterator = locationList.listIterator(); locationIterator = results.listIterator();
if (!options.isForward()) { if (!options.isForward()) {
// position iterator to end so that previous() will work // position iterator to end so that previous() will work
while (locationIterator.hasNext()) { while (locationIterator.hasNext()) {
@@ -16,9 +16,9 @@
package ghidra.app.plugin.core.searchtext; package ghidra.app.plugin.core.searchtext;
import ghidra.app.nav.Navigatable; import ghidra.app.nav.Navigatable;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.framework.model.DomainObjectException; import ghidra.framework.model.DomainObjectException;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.task.Task; import ghidra.util.task.Task;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
@@ -30,7 +30,7 @@ class SearchTask extends Task {
private Searcher textSearcher; private Searcher textSearcher;
private Navigatable navigatable; private Navigatable navigatable;
private ProgramLocation loc; private TextSearchResult result;
private boolean isCanceled; private boolean isCanceled;
private Program program; private Program program;
@@ -59,7 +59,7 @@ class SearchTask extends Task {
monitor.setMessage("Searching..."); monitor.setMessage("Searching...");
textSearcher.setMonitor(monitor); textSearcher.setMonitor(monitor);
try { try {
loc = textSearcher.search(); result = textSearcher.search();
} }
catch (Exception e) { catch (Exception e) {
if (!(e instanceof DomainObjectException)) { if (!(e instanceof DomainObjectException)) {
@@ -76,8 +76,8 @@ class SearchTask extends Task {
return navigatable; return navigatable;
} }
ProgramLocation getSearchLocation() { TextSearchResult getSearchLocation() {
return loc; return result;
} }
/** /**
@@ -15,8 +15,7 @@
*/ */
package ghidra.app.plugin.core.searchtext; package ghidra.app.plugin.core.searchtext;
import java.awt.Component; import java.awt.*;
import java.awt.KeyboardFocusManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@@ -24,6 +23,8 @@ import java.util.regex.Pattern;
import javax.swing.Icon; import javax.swing.Icon;
import org.apache.commons.lang3.StringUtils;
import docking.*; import docking.*;
import docking.action.builder.ActionBuilder; import docking.action.builder.ActionBuilder;
import docking.tool.ToolConstants; import docking.tool.ToolConstants;
@@ -37,13 +38,16 @@ import ghidra.app.nav.Navigatable;
import ghidra.app.nav.NavigatableRemovalListener; import ghidra.app.nav.NavigatableRemovalListener;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.ProgramPlugin; import ghidra.app.plugin.ProgramPlugin;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.app.plugin.core.searchtext.databasesearcher.ProgramDatabaseSearchTableModel; import ghidra.app.plugin.core.searchtext.databasesearcher.ProgramDatabaseSearchTableModel;
import ghidra.app.plugin.core.searchtext.databasesearcher.ProgramDatabaseSearcher; import ghidra.app.plugin.core.searchtext.databasesearcher.ProgramDatabaseSearcher;
import ghidra.app.plugin.core.table.TableComponentProvider; import ghidra.app.plugin.core.table.TableComponentProvider;
import ghidra.app.services.*; import ghidra.app.services.GoToService;
import ghidra.app.services.ProgramManager;
import ghidra.app.util.*; import ghidra.app.util.*;
import ghidra.app.util.query.TableService; import ghidra.app.util.query.TableService;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.model.DomainObject; import ghidra.framework.model.DomainObject;
import ghidra.framework.options.OptionsChangeListener; import ghidra.framework.options.OptionsChangeListener;
import ghidra.framework.options.ToolOptions; import ghidra.framework.options.ToolOptions;
@@ -83,7 +87,7 @@ import ghidra.util.task.*;
"on the entire program. Multiple matches are displayed " + "on the entire program. Multiple matches are displayed " +
"in a query results table. An option allows the search results " + "in a query results table. An option allows the search results " +
"to be highlighted in the Code Browser.", "to be highlighted in the Code Browser.",
servicesRequired = { ProgramManager.class, GoToService.class, CodeViewerService.class /*, TableService.class */ } servicesRequired = { ProgramManager.class, GoToService.class }
) )
//@formatter:on //@formatter:on
public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeListener, TaskListener, public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeListener, TaskListener,
@@ -92,7 +96,6 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
private static final Icon SEARCH_MARKER_ICON = new GIcon("icon.base.search.marker"); private static final Icon SEARCH_MARKER_ICON = new GIcon("icon.base.search.marker");
private static final String DESCRIPTION = "Search program text for string"; private static final String DESCRIPTION = "Search program text for string";
private final static Highlight[] NO_HIGHLIGHTS = new Highlight[0];
private boolean waitingForSearchAll; private boolean waitingForSearchAll;
private SearchTextDialog searchDialog; private SearchTextDialog searchDialog;
@@ -142,20 +145,22 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
return; return;
} }
ProgramLocation loc = searchTask.getSearchLocation(); TextSearchResult result = searchTask.getSearchLocation();
Searcher textSearcher = searchTask.getTextSearcher(); Searcher textSearcher = searchTask.getTextSearcher();
SearchOptions searchOptions = textSearcher.getSearchOptions(); SearchOptions searchOptions = textSearcher.getSearchOptions();
if (loc != null && loc.equals(currentLocation)) { if (result == null) {
searchDialog.setStatusText("Not found");
}
else if (result.programLocation().equals(currentLocation)) {
searchNext(searchTask.getProgram(), searchNavigatable, textSearcher); searchNext(searchTask.getProgram(), searchNavigatable, textSearcher);
} }
else if (loc != null) {
searchDialog.setStatusText("");
if (goToService.goTo(searchNavigatable, loc, program)) {
new HighlightHandler(searchNavigatable, searchOptions, null, program, loc);
}
}
else { else {
searchDialog.setStatusText("Not found"); searchDialog.setStatusText("");
ProgramLocation loc = result.programLocation();
if (goToService.goTo(searchNavigatable, loc, program)) {
new SearchTextHighlightProvider(searchNavigatable, searchOptions, null, program,
result);
}
} }
lastSearchedText = searchOptions.getText(); lastSearchedText = searchOptions.getText();
@@ -324,7 +329,8 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
searchAllTaskMonitor = tablePanel.getTaskMonitor(); searchAllTaskMonitor = tablePanel.getTaskMonitor();
tableProvider.setHelpLocation(new HelpLocation(HelpTopics.SEARCH, "SearchAllResults")); tableProvider.setHelpLocation(new HelpLocation(HelpTopics.SEARCH, "SearchAllResults"));
new HighlightHandler(searchNavigatable, searchOptions, tableProvider, searchProgram, null); new SearchTextHighlightProvider(searchNavigatable, searchOptions, tableProvider,
searchProgram, null);
} }
private TableComponentProvider<ProgramLocation> getTableResultsProvider( private TableComponentProvider<ProgramLocation> getTableResultsProvider(
@@ -593,20 +599,26 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
} }
} }
class HighlightHandler implements HighlightProvider, ComponentProviderActivationListener { private class SearchTextHighlightProvider
implements ListingHighlightProvider, ComponentProviderActivationListener {
private SearchOptions searchOptions; private SearchOptions searchOptions;
private TableComponentProvider<?> provider; private TableComponentProvider<?> provider;
private Program highlightProgram; private Program highlightProgram;
private final Navigatable highlightNavigatable; private final Navigatable highlightNavigatable;
private ProgramLocation loc; private boolean showAllResults;
HighlightHandler(Navigatable navigatable, SearchOptions searchOptions, // this is non-null for a single search
TableComponentProvider<?> provider, Program program, ProgramLocation loc) { private TextSearchResult searchResult;
SearchTextHighlightProvider(Navigatable navigatable, SearchOptions searchOptions,
TableComponentProvider<?> provider, Program program,
TextSearchResult searchResult) {
highlightNavigatable = navigatable; highlightNavigatable = navigatable;
this.searchOptions = searchOptions; this.searchOptions = searchOptions;
this.provider = provider; this.provider = provider;
this.highlightProgram = program; this.highlightProgram = program;
this.loc = loc; this.searchResult = searchResult;
this.showAllResults = searchResult == null;
if (provider != null) { if (provider != null) {
provider.addActivationListener(this); provider.addActivationListener(this);
@@ -615,8 +627,10 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
} }
@Override @Override
public Highlight[] getHighlights(String text, Object obj, public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass, int cursorTextOffset) {
Class<? extends FieldFactory> fieldFactoryClass = field.getFieldFactory().getClass();
if (!doHighlight) { if (!doHighlight) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
@@ -625,7 +639,7 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
if (!shouldHighlight(fieldFactoryClass, obj)) { if (!shouldHighlight(field)) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
@@ -634,50 +648,93 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
return getHighlights(text, cursorTextOffset); if (showAllResults) {
return getAllHighlights(text, cursorTextOffset);
}
Address address = searchResult.programLocation().getAddress();
ProxyObj<?> proxy = field.getProxy();
if (proxy.contains(address)) {
return getSingleSearchHighlight(text, field, cursorTextOffset);
}
return NO_HIGHLIGHTS;
} }
private Highlight[] getHighlights(String text, int cursorTextOffset) { private Highlight[] getAllHighlights(String text, int cursorTextOffset) {
String matchStr = searchOptions.getText().trim(); String searchText = searchOptions.getText();
if (matchStr == null || text == null) { if (StringUtils.isBlank(searchText) || StringUtils.isBlank(text)) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
List<Highlight> list = new ArrayList<>(); List<Highlight> list = new ArrayList<>();
Pattern regexp = Pattern regexp =
UserSearchUtils.createSearchPattern(matchStr, searchOptions.isCaseSensitive()); UserSearchUtils.createSearchPattern(searchText, searchOptions.isCaseSensitive());
Matcher matcher = regexp.matcher(text); Matcher matcher = regexp.matcher(text);
while (matcher.find()) { while (matcher.find()) {
int start = matcher.start(); int start = matcher.start();
int end = matcher.end() - 1; int end = matcher.end() - 1;
Color hlColor = PluginConstants.SEARCH_HIGHLIGHT_COLOR;
if (start <= cursorTextOffset && end >= cursorTextOffset) { if (start <= cursorTextOffset && end >= cursorTextOffset) {
list.add(new Highlight(start, end, // change the highlight color when in the field so it stands out
PluginConstants.SEARCH_HIGHLIGHT_CURRENT_ADDR_COLOR)); hlColor = PluginConstants.SEARCH_HIGHLIGHT_CURRENT_ADDR_COLOR;
}
else if (loc == null) { // only add in matches around current match if loc is null
// meaning that this is a one at a time search and not a table
// of results.
list.add(new Highlight(start, end,
PluginConstants.SEARCH_HIGHLIGHT_CURRENT_ADDR_COLOR));
} }
list.add(new Highlight(start, end, hlColor));
} }
if (list.size() == 0) { if (list.isEmpty()) {
return NO_HIGHLIGHTS; return NO_HIGHLIGHTS;
} }
Highlight[] h = new Highlight[list.size()]; return list.toArray(Highlight[]::new);
return list.toArray(h);
} }
/** private Highlight[] getSingleSearchHighlight(String text, ListingField field,
* Return whether the field for the given factory class should be highlighted; compare int cursorTextOffset) {
* against the search options
* String searchText = searchOptions.getText();
* @param factoryClass field factory class if (StringUtils.isBlank(searchText) || StringUtils.isBlank(text)) {
* @param obj object associated with the field, e.g. CodeUnit return NO_HIGHLIGHTS;
*/ }
private boolean shouldHighlight(Class<?> factoryClass, Object obj) {
FieldFactory fieldFactory = field.getFieldFactory();
ProgramLocation loc = searchResult.programLocation();
if (!fieldFactory.supportsLocation(field, loc)) {
return NO_HIGHLIGHTS;
}
int charOffset = searchResult.offset();
int searchStart = charOffset;
int searchEnd = searchStart + searchText.length();
Pattern regexp =
UserSearchUtils.createSearchPattern(searchText, searchOptions.isCaseSensitive());
Matcher matcher = regexp.matcher(text);
while (matcher.find()) {
int start = matcher.start();
int end = matcher.end();
// ensure the particular regex match is the actual search result
if (start == searchStart && end == searchEnd) {
Color hlColor = PluginConstants.SEARCH_HIGHLIGHT_COLOR;
if (start <= cursorTextOffset && end >= cursorTextOffset) {
// change the highlight color when in the field so it stands out
hlColor = PluginConstants.SEARCH_HIGHLIGHT_CURRENT_ADDR_COLOR;
}
// this is the matching search hit for a single search
int endEx = end - 1;
return new Highlight[] { new Highlight(start, endEx, hlColor) };
}
}
return NO_HIGHLIGHTS;
}
private boolean shouldHighlight(ListingField field) {
ProxyObj<?> proxy = field.getProxy();
Object obj = proxy.getObject();
Program navigatableProgram = navigatable == null ? null : navigatable.getProgram(); Program navigatableProgram = navigatable == null ? null : navigatable.getProgram();
if (navigatableProgram != highlightProgram) { if (navigatableProgram != highlightProgram) {
return false; return false;
@@ -686,6 +743,8 @@ public class SearchTextPlugin extends ProgramPlugin implements OptionsChangeList
if (searchOptions.searchAllFields()) { if (searchOptions.searchAllFields()) {
return true; return true;
} }
Class<? extends FieldFactory> factoryClass = field.getFieldFactory().getClass();
if (searchOptions.searchComments()) { if (searchOptions.searchComments()) {
if (factoryClass == PreCommentFieldFactory.class || if (factoryClass == PreCommentFieldFactory.class ||
factoryClass == PlateFieldFactory.class || factoryClass == PlateFieldFactory.class ||
@@ -27,7 +27,7 @@ public interface Searcher {
* Get the next program location. * Get the next program location.
* @return null if there is no next program location. * @return null if there is no next program location.
*/ */
public ProgramLocation search(); public TextSearchResult search();
/** /**
* Set the task monitor. * Set the task monitor.
@@ -40,4 +40,15 @@ public interface Searcher {
* @return the search option * @return the search option
*/ */
public SearchOptions getSearchOptions(); public SearchOptions getSearchOptions();
/**
* A record object that represents a single search result
*
* @param programLocation the program location of the search result.
* @param offset the offset in the *model*'s text of the search result; this value will be from
* 0 to text.length(), where text is a single string for all text in the given field.
*/
public record TextSearchResult(ProgramLocation programLocation, int offset) {
// stub
}
} }
@@ -19,6 +19,7 @@ import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.util.*; import ghidra.program.util.*;
@@ -52,7 +53,7 @@ public class CommentFieldSearcher extends ProgramDatabaseFieldSearcher {
} }
@Override @Override
protected Address advance(List<ProgramLocation> currentMatches) { protected Address advance(List<TextSearchResult> currentMatches) {
Address nextAddress = iterator.next(); Address nextAddress = iterator.next();
if (nextAddress != null) { if (nextAddress != null) {
findMatchesForCurrentAddress(nextAddress, currentMatches); findMatchesForCurrentAddress(nextAddress, currentMatches);
@@ -61,7 +62,7 @@ public class CommentFieldSearcher extends ProgramDatabaseFieldSearcher {
} }
private void findMatchesForCurrentAddress(Address address, private void findMatchesForCurrentAddress(Address address,
List<ProgramLocation> currentMatches) { List<TextSearchResult> currentMatches) {
String comment = program.getListing().getComment(commentType, address); String comment = program.getListing().getComment(commentType, address);
if (comment == null) { if (comment == null) {
return; return;
@@ -70,14 +71,15 @@ public class CommentFieldSearcher extends ProgramDatabaseFieldSearcher {
Matcher matcher = pattern.matcher(cleanedUpComment); Matcher matcher = pattern.matcher(cleanedUpComment);
while (matcher.find()) { while (matcher.find()) {
int index = matcher.start(); int index = matcher.start();
currentMatches.add(getCommentLocation(comment, index, address)); currentMatches
.add(new TextSearchResult(getCommentLocation(comment, index, address), index));
} }
} }
private ProgramLocation getCommentLocation(String commentStr, int index, Address address) { private ProgramLocation getCommentLocation(String commentStr, int index, Address address) {
String[] comments = StringUtilities.toLines(commentStr); String[] comments = StringUtilities.toLines(commentStr);
int rowIndex = findRowIndex(comments, index); int rowIndex = findRowIndex(comments, index);
int charOffset = findCharOffset(index, rowIndex, comments); int charOffset = getRelativeCharOffset(index, rowIndex, comments);
int[] dataPath = getDataComponentPath(address); int[] dataPath = getDataComponentPath(address);
switch (commentType) { switch (commentType) {
case CodeUnit.EOL_COMMENT: case CodeUnit.EOL_COMMENT:
@@ -114,12 +116,12 @@ public class CommentFieldSearcher extends ProgramDatabaseFieldSearcher {
return null; return null;
} }
private int findCharOffset(int index, int rowIndex, String[] opStrings) { private int getRelativeCharOffset(int index, int rowIndex, String[] comments) {
int totalBeforeOpIndex = 0; int preceding = 0;
for (int i = 0; i < rowIndex; i++) { for (int i = 0; i < rowIndex; i++) {
totalBeforeOpIndex += opStrings[i].length(); preceding += comments[i].length();
} }
return index - totalBeforeOpIndex; return index - preceding;
} }
private int findRowIndex(String[] commentStrings, int index) { private int findRowIndex(String[] commentStrings, int index) {
@@ -15,15 +15,16 @@
*/ */
package ghidra.app.plugin.core.searchtext.databasesearcher; package ghidra.app.plugin.core.searchtext.databasesearcher;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.util.*; import ghidra.program.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DataMnemonicOperandFieldSearcher extends ProgramDatabaseFieldSearcher { public class DataMnemonicOperandFieldSearcher extends ProgramDatabaseFieldSearcher {
private DataIterator iterator; private DataIterator iterator;
private CodeUnitFormat format; private CodeUnitFormat format;
@@ -75,7 +76,7 @@ public class DataMnemonicOperandFieldSearcher extends ProgramDatabaseFieldSearch
} }
@Override @Override
protected Address advance(List<ProgramLocation> currentMatches) { protected Address advance(List<TextSearchResult> currentMatches) {
Data data = iterator.next(); Data data = iterator.next();
Address nextAddress = null; Address nextAddress = null;
if (data != null) { if (data != null) {
@@ -85,7 +86,7 @@ public class DataMnemonicOperandFieldSearcher extends ProgramDatabaseFieldSearch
return nextAddress; return nextAddress;
} }
private void findMatchesForCurrentAddress(Data data, List<ProgramLocation> currentMatches) { private void findMatchesForCurrentAddress(Data data, List<TextSearchResult> currentMatches) {
StringBuffer searchStrBuf = new StringBuffer(); StringBuffer searchStrBuf = new StringBuffer();
String mnemonicString = ""; String mnemonicString = "";
String operandString = ""; String operandString = "";
@@ -122,16 +123,17 @@ public class DataMnemonicOperandFieldSearcher extends ProgramDatabaseFieldSearch
} }
} }
private void addOperandMatch(Data data, List<ProgramLocation> currentMatches, private void addOperandMatch(Data data, List<TextSearchResult> currentMatches,
String mnemonicString, String operandString, Address address, int index) { String mnemonicString, String operandString, Address address, int index) {
if (!doOperands) { if (!doOperands) {
return; return;
} }
currentMatches.add(new OperandFieldLocation(program, address, data.getComponentPath(), currentMatches.add(
null, operandString, 0, index - mnemonicString.length() - 1)); new TextSearchResult(new OperandFieldLocation(program, address, data.getComponentPath(),
null, operandString, 0, index - mnemonicString.length() - 1), index));
} }
private void addMnemonicMatch(List<ProgramLocation> currentMatches, String mnemonicString, private void addMnemonicMatch(List<TextSearchResult> currentMatches, String mnemonicString,
Address address, int index, int endIndex) { Address address, int index, int endIndex) {
if (!doMnemonics) { if (!doMnemonics) {
return; return;
@@ -140,7 +142,7 @@ public class DataMnemonicOperandFieldSearcher extends ProgramDatabaseFieldSearch
if (endIndex > mnemonicString.length()) { if (endIndex > mnemonicString.length()) {
return; return;
} }
currentMatches.add(new MnemonicFieldLocation(program, address, null, null, mnemonicString, currentMatches.add(new TextSearchResult(
index)); new MnemonicFieldLocation(program, address, null, null, mnemonicString, index), index));
} }
} }
@@ -20,6 +20,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import ghidra.app.plugin.core.navigation.FunctionUtils; import ghidra.app.plugin.core.navigation.FunctionUtils;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
@@ -46,7 +47,7 @@ public class FunctionFieldSearcher extends ProgramDatabaseFieldSearcher {
} }
@Override @Override
protected Address advance(List<ProgramLocation> currentMatches) { protected Address advance(List<TextSearchResult> currentMatches) {
if (iterator.hasNext()) { if (iterator.hasNext()) {
Function function = iterator.next(); Function function = iterator.next();
Address nextAddress = null; Address nextAddress = null;
@@ -62,34 +63,34 @@ public class FunctionFieldSearcher extends ProgramDatabaseFieldSearcher {
} }
private void findMatchesForCurrentFunction(Function function, private void findMatchesForCurrentFunction(Function function,
List<ProgramLocation> currentMatches) { List<TextSearchResult> currentMatches) {
findCommentMatches(function, currentMatches); findCommentMatches(function, currentMatches);
findSignatureMatches(function, currentMatches); findSignatureMatches(function, currentMatches);
findVariableMatches(function, currentMatches); findVariableMatches(function, currentMatches);
} }
private void findVariableMatches(Function function, List<ProgramLocation> currentMatches) { private void findVariableMatches(Function function, List<TextSearchResult> currentMatches) {
Parameter[] parameters = function.getParameters(); Parameter[] parameters = function.getParameters();
for (int i = 0; i < parameters.length; i++) { for (Parameter parameter : parameters) {
checkTypeString(parameters[i], currentMatches); checkTypeString(parameter, currentMatches);
checkName(parameters[i], currentMatches); checkName(parameter, currentMatches);
checkStorage(parameters[i], currentMatches); checkStorage(parameter, currentMatches);
checkComment(parameters[i], currentMatches); checkComment(parameter, currentMatches);
} }
Variable[] localVariables = function.getLocalVariables(); Variable[] localVariables = function.getLocalVariables();
for (int i = 0; i < localVariables.length; i++) { for (Variable localVariable : localVariables) {
checkTypeString(localVariables[i], currentMatches); checkTypeString(localVariable, currentMatches);
checkName(localVariables[i], currentMatches); checkName(localVariable, currentMatches);
checkStorage(localVariables[i], currentMatches); checkStorage(localVariable, currentMatches);
checkComment(localVariables[i], currentMatches); checkComment(localVariable, currentMatches);
} }
} }
private void checkTypeString(Variable variable, List<ProgramLocation> currentMatches) { private void checkTypeString(Variable variable, List<TextSearchResult> currentMatches) {
DataType dt; DataType dt;
if (variable instanceof Parameter) { if (variable instanceof Parameter) {
dt = ((Parameter)variable).getFormalDataType(); dt = ((Parameter) variable).getFormalDataType();
} }
else { else {
dt = variable.getDataType(); dt = variable.getDataType();
@@ -102,29 +103,32 @@ public class FunctionFieldSearcher extends ProgramDatabaseFieldSearcher {
Matcher matcher = pattern.matcher(searchString); Matcher matcher = pattern.matcher(searchString);
while (matcher.find()) { while (matcher.find()) {
int index = matcher.start(); int index = matcher.start();
currentMatches.add(new VariableTypeFieldLocation(program, variable, index)); currentMatches.add(new TextSearchResult(
new VariableTypeFieldLocation(program, variable, index), index));
} }
} }
private void checkName(Variable variable, List<ProgramLocation> currentMatches) { private void checkName(Variable variable, List<TextSearchResult> currentMatches) {
String searchString = variable.getName(); String searchString = variable.getName();
Matcher matcher = pattern.matcher(searchString); Matcher matcher = pattern.matcher(searchString);
while (matcher.find()) { while (matcher.find()) {
int index = matcher.start(); int index = matcher.start();
currentMatches.add(new VariableNameFieldLocation(program, variable, index)); currentMatches.add(new TextSearchResult(
new VariableNameFieldLocation(program, variable, index), index));
} }
} }
private void checkStorage(Variable var, List<ProgramLocation> currentMatches) { private void checkStorage(Variable var, List<TextSearchResult> currentMatches) {
String searchString = var.getVariableStorage().toString(); String searchString = var.getVariableStorage().toString();
Matcher matcher = pattern.matcher(searchString); Matcher matcher = pattern.matcher(searchString);
while (matcher.find()) { while (matcher.find()) {
int index = matcher.start(); int index = matcher.start();
currentMatches.add(new VariableLocFieldLocation(program, var, index)); currentMatches.add(
new TextSearchResult(new VariableLocFieldLocation(program, var, index), index));
} }
} }
private void checkComment(Variable variable, List<ProgramLocation> currentMatches) { private void checkComment(Variable variable, List<TextSearchResult> currentMatches) {
String searchString = variable.getComment(); String searchString = variable.getComment();
if (searchString == null) { if (searchString == null) {
return; return;
@@ -132,23 +136,27 @@ public class FunctionFieldSearcher extends ProgramDatabaseFieldSearcher {
Matcher matcher = pattern.matcher(searchString); Matcher matcher = pattern.matcher(searchString);
while (matcher.find()) { while (matcher.find()) {
int index = matcher.start(); int index = matcher.start();
currentMatches.add(new VariableCommentFieldLocation(program, variable, index)); currentMatches.add(
new TextSearchResult(new VariableCommentFieldLocation(program, variable, index),
index));
} }
} }
private void findSignatureMatches(Function function, List<ProgramLocation> currentMatches) { private void findSignatureMatches(Function function, List<TextSearchResult> currentMatches) {
String signature = function.getPrototypeString(false, false); String signature = function.getPrototypeString(false, false);
Matcher matcher = pattern.matcher(signature); Matcher matcher = pattern.matcher(signature);
Address address = function.getEntryPoint(); Address address = function.getEntryPoint();
int callingConventionOffset = FunctionUtils.getCallingConventionSignatureOffset(function); int callingConventionOffset = FunctionUtils.getCallingConventionSignatureOffset(function);
while (matcher.find()) { while (matcher.find()) {
int index = matcher.start(); int index = matcher.start();
currentMatches.add(new FunctionSignatureFieldLocation(program, address, null, index + currentMatches.add(new TextSearchResult(
callingConventionOffset, signature)); new FunctionSignatureFieldLocation(program, address, null, index +
callingConventionOffset, signature),
index));
} }
} }
private void findCommentMatches(Function function, List<ProgramLocation> currentMatches) { private void findCommentMatches(Function function, List<TextSearchResult> currentMatches) {
String functionComment = function.getRepeatableComment(); String functionComment = function.getRepeatableComment();
if (functionComment == null) { if (functionComment == null) {
@@ -159,7 +167,8 @@ public class FunctionFieldSearcher extends ProgramDatabaseFieldSearcher {
Address address = function.getEntryPoint(); Address address = function.getEntryPoint();
while (matcher.find()) { while (matcher.find()) {
int index = matcher.start(); int index = matcher.start();
currentMatches.add(getFunctionCommentLocation(functionComment, index, address)); currentMatches.add(new TextSearchResult(
getFunctionCommentLocation(functionComment, index, address), index));
} }
} }
@@ -19,6 +19,7 @@ import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
@@ -74,7 +75,7 @@ public class InstructionMnemonicOperandFieldSearcher extends ProgramDatabaseFiel
} }
@Override @Override
protected Address advance(List<ProgramLocation> currentMatches) { protected Address advance(List<TextSearchResult> currentMatches) {
Instruction instruction = iterator.hasNext() ? iterator.next() : null; Instruction instruction = iterator.hasNext() ? iterator.next() : null;
Address nextAddress = null; Address nextAddress = null;
if (instruction != null) { if (instruction != null) {
@@ -85,7 +86,7 @@ public class InstructionMnemonicOperandFieldSearcher extends ProgramDatabaseFiel
} }
private void findMatchesForCurrentAddress(Instruction instruction, private void findMatchesForCurrentAddress(Instruction instruction,
List<ProgramLocation> currentMatches) { List<TextSearchResult> currentMatches) {
String mnemonicString = instruction.getMnemonicString(); String mnemonicString = instruction.getMnemonicString();
String[] opStrings = getOperandStrings(instruction); String[] opStrings = getOperandStrings(instruction);
Matcher matcher = pattern.matcher(combineStrings(mnemonicString, opStrings)); Matcher matcher = pattern.matcher(combineStrings(mnemonicString, opStrings));
@@ -103,18 +104,18 @@ public class InstructionMnemonicOperandFieldSearcher extends ProgramDatabaseFiel
} }
} }
private void addOperandMatch(Instruction instruction, List<ProgramLocation> currentMatches, private void addOperandMatch(Instruction instruction, List<TextSearchResult> currentMatches,
String[] opStrings, Address address, int index) { String[] opStrings, Address address, int index) {
if (!doOperands) { if (!doOperands) {
return; return;
} }
int opIndex = findOpIndex(opStrings, index); int opIndex = findOpIndex(opStrings, index);
int charOffset = findCharOffset(index, opIndex, opStrings); int charOffset = findCharOffset(index, opIndex, opStrings);
currentMatches.add(new OperandFieldLocation(program, address, null, currentMatches.add(new TextSearchResult(new OperandFieldLocation(program, address, null,
instruction.getAddress(opIndex), opStrings[opIndex], opIndex, charOffset)); instruction.getAddress(opIndex), opStrings[opIndex], opIndex, charOffset), index));
} }
private void addMnemonicMatch(List<ProgramLocation> currentMatches, Address address, private void addMnemonicMatch(List<TextSearchResult> currentMatches, Address address,
String mnemonicString, int startIndex, int endIndex) { String mnemonicString, int startIndex, int endIndex) {
if (!doMnemonics) { if (!doMnemonics) {
return; return;
@@ -124,7 +125,9 @@ public class InstructionMnemonicOperandFieldSearcher extends ProgramDatabaseFiel
return; return;
} }
currentMatches.add(new MnemonicFieldLocation(program, address, null, null, mnemonicString, currentMatches.add(new TextSearchResult(
new MnemonicFieldLocation(program, address, null, null, mnemonicString,
startIndex),
startIndex)); startIndex));
} }
@@ -20,6 +20,7 @@ import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.program.model.address.*; import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.*; import ghidra.program.model.symbol.*;
@@ -29,13 +30,11 @@ import ghidra.program.util.ProgramLocation;
public class LabelFieldSearcher extends ProgramDatabaseFieldSearcher { public class LabelFieldSearcher extends ProgramDatabaseFieldSearcher {
private AddressIterator iterator; private AddressIterator iterator;
private SymbolTable symbolTable; private SymbolTable symbolTable;
private Program program;
public LabelFieldSearcher(Program program, ProgramLocation startLoc, AddressSetView set, public LabelFieldSearcher(Program program, ProgramLocation startLoc, AddressSetView set,
boolean forward, Pattern pattern) { boolean forward, Pattern pattern) {
super(pattern, forward, startLoc, set); super(pattern, forward, startLoc, set);
this.program = program;
this.symbolTable = program.getSymbolTable(); this.symbolTable = program.getSymbolTable();
SymbolIterator symbolIterator; SymbolIterator symbolIterator;
@@ -48,15 +47,15 @@ public class LabelFieldSearcher extends ProgramDatabaseFieldSearcher {
else { else {
symbolIterator = symbolIterator =
program.getSymbolTable().getPrimarySymbolIterator(startLoc.getAddress(), forward); program.getSymbolTable().getPrimarySymbolIterator(startLoc.getAddress(), forward);
refIterator = program.getReferenceManager().getReferenceDestinationIterator( refIterator = program.getReferenceManager()
startLoc.getAddress(), forward); .getReferenceDestinationIterator(
startLoc.getAddress(), forward);
} }
iterator = new SymbolAddressIterator(symbolIterator, refIterator, forward); iterator = new SymbolAddressIterator(symbolIterator, refIterator, forward);
} }
@Override @Override
protected Address advance(List<ProgramLocation> currentMatches) { protected Address advance(List<TextSearchResult> currentMatches) {
Address nextAddress = iterator.next(); Address nextAddress = iterator.next();
if (nextAddress == null) { if (nextAddress == null) {
return null; return null;
@@ -66,14 +65,15 @@ public class LabelFieldSearcher extends ProgramDatabaseFieldSearcher {
} }
private void findMatchesForCurrentAddress(Address address, private void findMatchesForCurrentAddress(Address address,
List<ProgramLocation> currentMatches) { List<TextSearchResult> currentMatches) {
Symbol[] symbols = symbolTable.getSymbols(address); Symbol[] symbols = symbolTable.getSymbols(address);
makePrimaryLastItem(symbols); makePrimaryLastItem(symbols);
for (Symbol symbol : symbols) { for (Symbol symbol : symbols) {
Matcher matcher = pattern.matcher(symbol.getName()); Matcher matcher = pattern.matcher(symbol.getName());
while (matcher.find()) { while (matcher.find()) {
int charOffset = matcher.start(); int charOffset = matcher.start();
currentMatches.add(new LabelFieldLocation(symbol, 0, charOffset)); currentMatches.add(new TextSearchResult(
new LabelFieldLocation(symbol, 0, charOffset), charOffset));
} }
} }
} }
@@ -110,9 +110,6 @@ public class LabelFieldSearcher extends ProgramDatabaseFieldSearcher {
nextRefAddress = getNextRefAddress(); nextRefAddress = getNextRefAddress();
} }
/**
* @see java.util.Iterator#remove()
*/
@Override @Override
public void remove() { public void remove() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
@@ -15,49 +15,54 @@
*/ */
package ghidra.app.plugin.core.searchtext.databasesearcher; package ghidra.app.plugin.core.searchtext.databasesearcher;
import java.util.*;
import java.util.regex.Pattern;
import ghidra.app.plugin.core.searchtext.Searcher.TextSearchResult;
import ghidra.program.model.address.Address; import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView; import ghidra.program.model.address.AddressSetView;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import java.util.*;
import java.util.regex.Pattern;
public abstract class ProgramDatabaseFieldSearcher { public abstract class ProgramDatabaseFieldSearcher {
protected final Pattern pattern; protected final Pattern pattern;
protected final boolean forward; protected final boolean forward;
private Address currentAddress; private Address currentAddress;
private ProgramLocation startLocation; private ProgramLocation startLocation;
private List<ProgramLocation> matchesForCurrentAddress = new LinkedList<ProgramLocation>(); private List<TextSearchResult> matchesForCurrentAddress = new LinkedList<>();
protected ProgramDatabaseFieldSearcher(Pattern pattern, boolean forward, ProgramLocation startLoc, AddressSetView set) { protected ProgramDatabaseFieldSearcher(Pattern pattern, boolean forward,
ProgramLocation startLoc, AddressSetView set) {
this.pattern = pattern; this.pattern = pattern;
this.forward = forward; this.forward = forward;
this.startLocation = startLoc; this.startLocation = startLoc;
if (forward && set != null && !set.isEmpty() && startLoc != null && if (forward && set != null && !set.isEmpty() && startLoc != null &&
!set.getMinAddress().equals(startLoc.getAddress())) { !set.getMinAddress().equals(startLoc.getAddress())) {
throw new IllegalArgumentException("Start location and addressSet are inconsistent!"); throw new IllegalArgumentException("Start location and addressSet are inconsistent!");
} }
if (!forward && set != null && !set.isEmpty() && startLoc != null && if (!forward && set != null && !set.isEmpty() && startLoc != null &&
!set.getMaxAddress().equals(startLoc.getAddress())) { !set.getMaxAddress().equals(startLoc.getAddress())) {
throw new IllegalArgumentException("Start location and addressSet are inconsistent!"); throw new IllegalArgumentException("Start location and addressSet are inconsistent!");
} }
} }
private void initialize() { private void initialize() {
currentAddress = doAdvance(matchesForCurrentAddress); currentAddress = doAdvance(matchesForCurrentAddress);
trimMatchesForStartLocation( ); trimMatchesForStartLocation();
} }
private Address doAdvance(List<ProgramLocation> currentMatches) {
private Address doAdvance(List<TextSearchResult> currentMatches) {
Address address = advance(matchesForCurrentAddress); Address address = advance(matchesForCurrentAddress);
if (!forward) { if (!forward) {
Collections.reverse( matchesForCurrentAddress ); Collections.reverse(matchesForCurrentAddress);
} }
return address; return address;
} }
protected abstract Address advance(List<ProgramLocation> currentMatches);
protected abstract Address advance(List<TextSearchResult> currentMatches);
public Address getNextSignificantAddress( Address address ) {
public Address getNextSignificantAddress(Address address) {
if (address == null) { if (address == null) {
initialize(); initialize();
return currentAddress; return currentAddress;
@@ -65,37 +70,37 @@ public abstract class ProgramDatabaseFieldSearcher {
if (currentAddress == null) { // we have no more records in our iterator. if (currentAddress == null) { // we have no more records in our iterator.
return null; return null;
} }
if (currentAddress.equals( address )) { // we need to move to the next record if (currentAddress.equals(address)) { // we need to move to the next record
currentAddress = doAdvance(matchesForCurrentAddress); currentAddress = doAdvance(matchesForCurrentAddress);
} }
return currentAddress; return currentAddress;
} }
public ProgramLocation getMatch() { public TextSearchResult getMatch() {
return matchesForCurrentAddress.remove( 0 ); return matchesForCurrentAddress.remove(0);
} }
public boolean hasMatch( Address address ) { public boolean hasMatch(Address address) {
if (!address.equals(currentAddress)) { if (!address.equals(currentAddress)) {
return false; return false;
} }
return !matchesForCurrentAddress.isEmpty(); return !matchesForCurrentAddress.isEmpty();
} }
private void trimMatchesForStartLocation( ) { private void trimMatchesForStartLocation() {
if (startLocation == null) { if (startLocation == null) {
return; return;
} }
if (!startLocation.getAddress().equals( currentAddress )) { if (!startLocation.getAddress().equals(currentAddress)) {
return; return;
} }
Iterator<ProgramLocation> it = matchesForCurrentAddress.iterator(); Iterator<TextSearchResult> it = matchesForCurrentAddress.iterator();
while(it.hasNext()) { while (it.hasNext()) {
ProgramLocation programLoc = it.next(); ProgramLocation programLoc = it.next().programLocation();
int compareVal = startLocation.compareTo( programLoc ); int compareVal = startLocation.compareTo(programLoc);
if ((forward && compareVal >=0) || if ((forward && compareVal >= 0) ||
(!forward && compareVal <=0 )) { (!forward && compareVal <= 0)) {
it.remove(); it.remove();
} }
} }
} }
@@ -82,7 +82,7 @@ public class ProgramDatabaseSearcher implements Searcher {
} }
@Override @Override
public ProgramLocation search() { public TextSearchResult search() {
List<ProgramDatabaseFieldSearcher> orderedSearchers = searchers; List<ProgramDatabaseFieldSearcher> orderedSearchers = searchers;
if (!searchOptions.isForward()) { if (!searchOptions.isForward()) {
orderedSearchers = new ArrayList<>(searchers); orderedSearchers = new ArrayList<>(searchers);
@@ -210,8 +210,9 @@ public class ProgramDatabaseSearcher implements Searcher {
} }
if (options.searchBothInstructionMnemonicAndOperands()) { if (options.searchBothInstructionMnemonicAndOperands()) {
searchers.add( searchers.add(
InstructionMnemonicOperandFieldSearcher.createInstructionMnemonicAndOperandFieldSearcher( InstructionMnemonicOperandFieldSearcher
program, adjustedStart, trimmedSet, forward, pattern, format)); .createInstructionMnemonicAndOperandFieldSearcher(
program, adjustedStart, trimmedSet, forward, pattern, format));
} }
if (options.searchOnlyInstructionMnemonics()) { if (options.searchOnlyInstructionMnemonics()) {
searchers.add( searchers.add(
@@ -21,7 +21,7 @@ import java.util.*;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.GhidraOptions; import ghidra.GhidraOptions;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.pcode.AttributedStringPcodeFormatter; import ghidra.app.util.pcode.AttributedStringPcodeFormatter;
import ghidra.app.util.viewer.field.*; import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
@@ -55,7 +55,7 @@ public class PcodeFieldFactory extends FieldFactory {
} }
public PcodeFieldFactory(String name, FieldFormatModel model, public PcodeFieldFactory(String name, FieldFormatModel model,
HighlightProvider highlightProvider, Options displayOptions, Options fieldOptions) { ListingHighlightProvider highlightProvider, Options displayOptions, Options fieldOptions) {
super(name, model, highlightProvider, displayOptions, fieldOptions); super(name, model, highlightProvider, displayOptions, fieldOptions);
setWidth(300); setWidth(300);
@@ -67,7 +67,7 @@ public class PcodeFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel myModel, HighlightProvider highlightProvider, public FieldFactory newInstance(FieldFormatModel myModel, ListingHighlightProvider highlightProvider,
ToolOptions options, ToolOptions fieldOptions) { ToolOptions options, ToolOptions fieldOptions) {
return new PcodeFieldFactory(FIELD_NAME, myModel, highlightProvider, options, fieldOptions); return new PcodeFieldFactory(FIELD_NAME, myModel, highlightProvider, options, fieldOptions);
} }
@@ -22,7 +22,7 @@ import docking.widgets.fieldpanel.FieldPanel;
import docking.widgets.fieldpanel.field.Field; import docking.widgets.fieldpanel.field.Field;
import ghidra.app.nav.Navigatable; import ghidra.app.nav.Navigatable;
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin; import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.ProgramDropProvider; import ghidra.app.util.ProgramDropProvider;
import ghidra.app.util.viewer.format.FormatManager; import ghidra.app.util.viewer.format.FormatManager;
import ghidra.app.util.viewer.listingpanel.*; import ghidra.app.util.viewer.listingpanel.*;
@@ -105,14 +105,14 @@ public interface CodeViewerService {
* @param provider The provider to set. * @param provider The provider to set.
* @param program The program with which to associate the given provider. * @param program The program with which to associate the given provider.
*/ */
public void setHighlightProvider(HighlightProvider provider, Program program); public void setHighlightProvider(ListingHighlightProvider provider, Program program);
/** /**
* Remove the highlight provider. * Remove the highlight provider.
* @param provider the provider to remove. * @param provider the provider to remove.
* @param program the program associated with the given provider. * @param program the program associated with the given provider.
*/ */
public void removeHighlightProvider(HighlightProvider provider, Program program); public void removeHighlightProvider(ListingHighlightProvider provider, Program program);
/** /**
* Set a listing panel on the code viewer. * Set a listing panel on the code viewer.
@@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* 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.
@@ -16,28 +15,27 @@
*/ */
package ghidra.app.util; package ghidra.app.util;
import ghidra.app.util.viewer.field.FieldFactory;
import docking.widgets.fieldpanel.support.Highlight; import docking.widgets.fieldpanel.support.Highlight;
import ghidra.app.util.viewer.field.ListingField;
import ghidra.program.model.listing.CodeUnit;
/** /**
* Provider of Highlight objects appropriate for the text, object, and FieldFactory class. * Provider of Highlight objects appropriate {@link ListingField}s.
*
*/ */
public interface HighlightProvider { public interface ListingHighlightProvider {
public static final Highlight[] EMPTY_HIGHLIGHT = new Highlight[0]; public static final Highlight[] NO_HIGHLIGHTS = new Highlight[0];
/** /**
* Get the highlights appropriate for the given text, object, and FieldFactory class. * Get the highlights appropriate for the given text
*
* @param text the entire text contained in the field, regardless of layout. * @param text the entire text contained in the field, regardless of layout.
* @param obj object that provides the information to be rendered (usually a code unit) * @param field the field being rendered. From this field you can get the field factory and
* @param fieldFactoryClass the class that indicates what type of field is being rendered. * the proxy object, which is usually a {@link CodeUnit}.
* For Example, address fields would have the AddressFieldFactory class. * @param cursorTextOffset the cursor position within the given text or -1 if no cursor in this
* @param cursorTextOffset the cursor position within the given text or -1 if no cursor in this field. * field.
* @return an array of highlight objects that indicate the location within the text string to * @return an array of highlight objects that indicate the location within the text string to
* be highlighted. * be highlighted.
*/ */
public Highlight[] getHighlights(String text, Object obj, public Highlight[] createHighlights(String text, ListingField field, int cursorTextOffset);
Class<? extends FieldFactory> fieldFactoryClass, int cursorTextOffset);
} }
@@ -17,7 +17,7 @@ package ghidra.app.util.viewer.field;
import java.awt.*; import java.awt.*;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.FunctionColors; import ghidra.app.util.viewer.field.ListingColors.FunctionColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.options.OptionsGui; import ghidra.app.util.viewer.options.OptionsGui;
@@ -65,7 +65,7 @@ public abstract class AbstractVariableFieldFactory extends FieldFactory {
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
protected AbstractVariableFieldFactory(String name, FieldFormatModel model, protected AbstractVariableFieldFactory(String name, FieldFormatModel model,
HighlightProvider highlightProvider, Options displayOptions, Options fieldOptions) { ListingHighlightProvider highlightProvider, Options displayOptions, Options fieldOptions) {
super(name, model, highlightProvider, displayOptions, fieldOptions); super(name, model, highlightProvider, displayOptions, fieldOptions);
} }
@@ -20,7 +20,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.*; import ghidra.framework.options.*;
@@ -63,7 +63,7 @@ public class AddressFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private AddressFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private AddressFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
initOptions(fieldOptions); initOptions(fieldOptions);
@@ -198,7 +198,7 @@ public class AddressFieldFactory extends FieldFactory {
@Override @Override
public FieldFactory newInstance(FieldFormatModel newModel, public FieldFactory newInstance(FieldFormatModel newModel,
HighlightProvider highlightStringProvider, ToolOptions toolOptions, ListingHighlightProvider highlightStringProvider, ToolOptions toolOptions,
ToolOptions fieldOptions) { ToolOptions fieldOptions) {
return new AddressFieldFactory(newModel, highlightStringProvider, toolOptions, return new AddressFieldFactory(newModel, highlightStringProvider, toolOptions,
fieldOptions); fieldOptions);
@@ -21,7 +21,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.RowColLocation; import docking.widgets.fieldpanel.support.RowColLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.format.FormatManager; import ghidra.app.util.viewer.format.FormatManager;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@@ -43,7 +43,7 @@ public class ArrayValuesFieldFactory extends FieldFactory {
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, public FieldFactory newInstance(FieldFormatModel formatModel,
HighlightProvider highlightProvider, ToolOptions toolOptions, ListingHighlightProvider highlightProvider, ToolOptions toolOptions,
ToolOptions fieldOptions) { ToolOptions fieldOptions) {
return new ArrayValuesFieldFactory(formatModel, highlightProvider, toolOptions, return new ArrayValuesFieldFactory(formatModel, highlightProvider, toolOptions,
fieldOptions); fieldOptions);
@@ -56,7 +56,7 @@ public class ArrayValuesFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private ArrayValuesFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private ArrayValuesFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
setupOptions(fieldOptions); setupOptions(fieldOptions);
@@ -20,7 +20,7 @@ import java.util.ArrayList;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.FunctionColors; import ghidra.app.util.viewer.field.ListingColors.FunctionColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@@ -50,7 +50,7 @@ public class AssignedVariableFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private AssignedVariableFieldFactory(FieldFormatModel model, HighlightProvider hsProvider, private AssignedVariableFieldFactory(FieldFormatModel model, ListingHighlightProvider hsProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions);
} }
@@ -134,7 +134,7 @@ public class AssignedVariableFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider hsProvider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider hsProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new AssignedVariableFieldFactory(formatModel, hsProvider, displayOptions, return new AssignedVariableFieldFactory(formatModel, hsProvider, displayOptions,
fieldOptions); fieldOptions);
@@ -27,7 +27,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.RowColLocation; import docking.widgets.fieldpanel.support.RowColLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
@@ -35,10 +35,12 @@ import ghidra.framework.options.ToolOptions;
import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataType;
import ghidra.program.model.data.Structure; import ghidra.program.model.data.Structure;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.util.BytesFieldLocation; import ghidra.program.util.BytesFieldLocation;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import ghidra.util.Msg;
/** /**
* Generates Bytes Fields. * Generates Bytes Fields.
@@ -81,7 +83,7 @@ public class BytesFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private BytesFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private BytesFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
@@ -171,22 +173,23 @@ public class BytesFieldFactory extends FieldFactory {
if (!enabled || !(obj instanceof CodeUnit)) { if (!enabled || !(obj instanceof CodeUnit)) {
return null; return null;
} }
CodeUnit cu = (CodeUnit) obj;
CodeUnit cu = (CodeUnit) obj;
int length = Math.min(cu.getLength(), 100); int length = Math.min(cu.getLength(), 100);
byte[] bytes = new byte[length]; byte[] bytes = new byte[length];
Memory memory = cu.getProgram().getMemory();
try { try {
length = cu.getProgram().getMemory().getBytes(cu.getAddress(), bytes); length = memory.getBytes(cu.getAddress(), bytes);
} }
catch (MemoryAccessException e) { catch (MemoryAccessException e) {
return null; return null;
} }
if (length == 0) { if (length == 0) {
return null; return null;
} }
if ((cu instanceof Instruction) && reverseInstByteOrdering && if ((cu instanceof Instruction) && reverseInstByteOrdering && !memory.isBigEndian()) {
!cu.getProgram().getMemory().isBigEndian()) {
int i = 0; int i = 0;
int j = length - 1; int j = length - 1;
while (j > i) { while (j > i) {
@@ -196,26 +199,24 @@ public class BytesFieldFactory extends FieldFactory {
} }
} }
int fieldElementLength = length / byteGroupSize; int groupLength = length / byteGroupSize;
int residual = length % byteGroupSize; int residual = length % byteGroupSize;
if (residual != 0) { if (residual != 0) {
fieldElementLength++; groupLength++;
} }
boolean wasTruncated = length != cu.getLength(); boolean wasTruncated = length != cu.getLength();
byte[] alignmentBytes = getAlignmentBytes(cu, wasTruncated); byte[] alignmentBytes = getAlignmentBytes(cu, wasTruncated);
int extraLen = getLengthForAlignmentBytes(alignmentBytes, residual); int extraLength = getLengthForAlignmentBytes(alignmentBytes, residual);
FieldElement[] elements = new FieldElement[groupLength + extraLength];
FieldElement[] aStrings = new FieldElement[fieldElementLength + extraLen]; boolean addDelimiter = extraLength != 0;
buildAttributedByteValues(elements, 0, bytes, length, 0, ListingColors.BYTES, addDelimiter);
buildAttributedByteValues(aStrings, 0, bytes, length, 0, ListingColors.BYTES, if (addDelimiter) {
extraLen != 0); buildAttributedByteValues(elements, groupLength, alignmentBytes,
if (extraLen != 0) {
buildAttributedByteValues(aStrings, fieldElementLength, alignmentBytes,
alignmentBytes.length, residual, ListingColors.BYTES_ALIGNMENT, false); alignmentBytes.length, residual, ListingColors.BYTES_ALIGNMENT, false);
} }
return ListingTextField.createPackedTextField(this, proxy, aStrings, startX + varWidth, return ListingTextField.createPackedTextField(this, proxy, elements, startX + varWidth,
width, maxDisplayLines, hlProvider); width, maxDisplayLines, hlProvider);
} }
@@ -242,9 +243,9 @@ public class BytesFieldFactory extends FieldFactory {
return null; return null;
} }
private int buildAttributedByteValues(FieldElement[] aStrings, int pos, byte[] bytes, int size, private int buildAttributedByteValues(FieldElement[] elements, int pos, byte[] bytes, int size,
int residual, Color c, boolean addDelimToLastGroup) { int residual, Color color, boolean addDelimiter) {
StringBuffer buffer = new StringBuffer(); StringBuilder buffer = new StringBuilder();
int groupSize = byteGroupSize - residual; int groupSize = byteGroupSize - residual;
int tempGroupSize = 0; int tempGroupSize = 0;
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
@@ -263,19 +264,20 @@ public class BytesFieldFactory extends FieldFactory {
if (tempGroupSize == groupSize) { if (tempGroupSize == groupSize) {
tempGroupSize = 0; tempGroupSize = 0;
groupSize = byteGroupSize; groupSize = byteGroupSize;
if (i < size - 1 || addDelimToLastGroup) { if (i < size - 1 || addDelimiter) {
buffer.append(delim); buffer.append(delim);
} }
AttributedString as = new AttributedString(buffer.toString(), c, getMetrics()); AttributedString as = new AttributedString(buffer.toString(), color, getMetrics());
aStrings[pos] = new TextFieldElement(as, pos, 0); elements[pos] = new TextFieldElement(as, pos, 0);
pos++; pos++;
buffer = new StringBuffer(); buffer = new StringBuilder();
} }
} }
// append incomplete byte group... // append incomplete byte group...
if (tempGroupSize > 0) { if (tempGroupSize > 0) {
AttributedString as = new AttributedString(buffer.toString(), c, getMetrics()); AttributedString as = new AttributedString(buffer.toString(), color, getMetrics());
aStrings[pos] = new TextFieldElement(as, pos, 0); elements[pos] = new TextFieldElement(as, pos, 0);
} }
return tempGroupSize; return tempGroupSize;
} }
@@ -310,8 +312,8 @@ public class BytesFieldFactory extends FieldFactory {
if (alignSize <= 0) { if (alignSize <= 0) {
return null; return null;
} }
int alignmentOffset = data.getParentOffset() + data.getLength();
int alignmentOffset = data.getParentOffset() + data.getLength();
byte[] bytes = new byte[alignSize]; byte[] bytes = new byte[alignSize];
parent.getBytes(bytes, alignmentOffset); parent.getBytes(bytes, alignmentOffset);
return bytes; return bytes;
@@ -319,13 +321,15 @@ public class BytesFieldFactory extends FieldFactory {
@Override @Override
public ProgramLocation getProgramLocation(int row, int col, ListingField bf) { public ProgramLocation getProgramLocation(int row, int col, ListingField bf) {
Msg.debug(this, "Bytes - getProgLoc() - row / col: " + row + " / " + col);
Object obj = bf.getProxy().getObject(); Object obj = bf.getProxy().getObject();
if (!(obj instanceof CodeUnit) || row < 0 || col < 0) { if (!(obj instanceof CodeUnit) || row < 0 || col < 0) {
return null; return null;
} }
CodeUnit cu = (CodeUnit) obj; CodeUnit cu = (CodeUnit) obj;
int[] cpath = null; int[] cpath = null;
if (cu instanceof Data) { if (cu instanceof Data) {
cpath = ((Data) cu).getComponentPath(); cpath = ((Data) cu).getComponentPath();
@@ -354,16 +358,15 @@ public class BytesFieldFactory extends FieldFactory {
int byteIndex = tokenIndex * byteGroupSize + getByteIndexInToken(tokenCharPos); int byteIndex = tokenIndex * byteGroupSize + getByteIndexInToken(tokenCharPos);
int charOffset = computeCharOffset(tokenCharPos); int charOffset = computeCharOffset(tokenCharPos);
return new BytesFieldLocation(cu.getProgram(), cu.getMinAddress(), return new BytesFieldLocation(cu.getProgram(), cu.getMinAddress(),
cu.getMinAddress().add(byteIndex), cpath, charOffset); cu.getMinAddress().add(byteIndex), cpath, charOffset);
} }
/** /**
* Computes how many bytes the the given column position represents. Normally * Computes how many bytes the the given column position represents. Normally this is just the
* this is just the column position / 2 (since each byte consists of two chars). There * column position / 2 (since each byte consists of two chars). There is a special case when
* is a special case when the col position is just past the last char of the token. In * the col position is just past the last char of the token. In this case, we want to return
* this case, we want to return the number of bytes in a token - 1; * the number of bytes in a token - 1;
*/ */
private int getByteIndexInToken(int col) { private int getByteIndexInToken(int col) {
if (col >= byteGroupSize * CHARS_IN_BYTE) { if (col >= byteGroupSize * CHARS_IN_BYTE) {
@@ -374,11 +377,10 @@ public class BytesFieldFactory extends FieldFactory {
/** /**
* Computes the character offset for a BytesFieldLocation based on the character column the * Computes the character offset for a BytesFieldLocation based on the character column the
* cursor is at in the token. BytesFieldLocation character offsets are always as if the group size is 1. * cursor is at in the token. BytesFieldLocation character offsets are always as if the group
* So for all positions except the last byte, it is just the column modulo 2. For the last byte, we have * size is 1. So for all positions except the last byte, it is just the column modulo 2. For
* to account for any columns past the last char. In this case, we have to subtract off * the last byte, we have to account for any columns past the last char. In this case, we have
* 2 for every byte before the last byte. * to subtract off 2 for every byte before the last byte.
*
*/ */
private int computeCharOffset(int col) { private int computeCharOffset(int col) {
if (col >= byteGroupSize * CHARS_IN_BYTE) { if (col >= byteGroupSize * CHARS_IN_BYTE) {
@@ -390,17 +392,16 @@ public class BytesFieldFactory extends FieldFactory {
@Override @Override
public FieldLocation getFieldLocation(ListingField bf, BigInteger index, int fieldNum, public FieldLocation getFieldLocation(ListingField bf, BigInteger index, int fieldNum,
ProgramLocation loc) { ProgramLocation loc) {
if (!(loc instanceof BytesFieldLocation)) { if (!(loc instanceof BytesFieldLocation)) {
return null; return null;
} }
Object obj = bf.getProxy().getObject(); Object obj = bf.getProxy().getObject();
if (!(obj instanceof CodeUnit)) { if (!(obj instanceof CodeUnit)) {
return null; return null;
} }
CodeUnit cu = (CodeUnit) obj; CodeUnit cu = (CodeUnit) obj;
BytesFieldLocation bytesLoc = (BytesFieldLocation) loc; BytesFieldLocation bytesLoc = (BytesFieldLocation) loc;
int byteIndex = bytesLoc.getByteIndex(); int byteIndex = bytesLoc.getByteIndex();
int columnInByte = bytesLoc.getColumnInByte(); int columnInByte = bytesLoc.getColumnInByte();
@@ -442,7 +443,8 @@ public class BytesFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel,
ListingHighlightProvider provider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new BytesFieldFactory(formatModel, provider, displayOptions, fieldOptions); return new BytesFieldFactory(formatModel, provider, displayOptions, fieldOptions);
} }
@@ -19,7 +19,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.format.FormatManager; import ghidra.app.util.viewer.format.FormatManager;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@@ -79,7 +79,7 @@ public class DummyFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider hlProvdier, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider hlProvdier,
ToolOptions options, ToolOptions fieldOptions) { ToolOptions options, ToolOptions fieldOptions) {
return this; return this;
} }
@@ -98,7 +98,7 @@ public class EolCommentFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private EolCommentFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private EolCommentFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
HelpLocation hl = new HelpLocation("CodeBrowserPlugin", "EOL_Comments_Field"); HelpLocation hl = new HelpLocation("CodeBrowserPlugin", "EOL_Comments_Field");
@@ -522,13 +522,13 @@ public class EolCommentFieldFactory extends FieldFactory {
if (!(obj instanceof CodeUnit)) { if (!(obj instanceof CodeUnit)) {
return null; return null;
} }
DisplayableEol displayableEol = DisplayableEol displayableEol =
new DisplayableEol((CodeUnit) obj, alwaysShowRepeatable, alwaysShowRefRepeatables, new DisplayableEol((CodeUnit) obj, alwaysShowRepeatable, alwaysShowRefRepeatables,
alwaysShowAutomatic, codeUnitFormatOptions.followReferencedPointers(), alwaysShowAutomatic, codeUnitFormatOptions.followReferencedPointers(),
maxDisplayLines, useAbbreviatedAutomatic, showAutomaticFunctions); maxDisplayLines, useAbbreviatedAutomatic, showAutomaticFunctions);
ListingTextField btf = (ListingTextField) bf; ListingTextField btf = (ListingTextField) bf;
RowColLocation eolRowCol = displayableEol.getRowCol((CommentFieldLocation) loc); RowColLocation eolRowCol = displayableEol.getRowCol((CommentFieldLocation) loc);
RowColLocation rcl = btf.dataToScreenLocation(eolRowCol.row(), eolRowCol.col()); RowColLocation rcl = btf.dataToScreenLocation(eolRowCol.row(), eolRowCol.col());
if (!hasSamePath(bf, loc)) { if (!hasSamePath(bf, loc)) {
@@ -548,7 +548,7 @@ public class EolCommentFieldFactory extends FieldFactory {
@Override @Override
public FieldFactory newInstance(FieldFormatModel fieldFormatModel, public FieldFactory newInstance(FieldFormatModel fieldFormatModel,
HighlightProvider highlightProvider, ToolOptions newDisplayOptions, ListingHighlightProvider highlightProvider, ToolOptions newDisplayOptions,
ToolOptions newFieldOptions) { ToolOptions newFieldOptions) {
return new EolCommentFieldFactory(fieldFormatModel, highlightProvider, newDisplayOptions, return new EolCommentFieldFactory(fieldFormatModel, highlightProvider, newDisplayOptions,
newFieldOptions); newFieldOptions);
@@ -16,7 +16,6 @@
package ghidra.app.util.viewer.field; package ghidra.app.util.viewer.field;
import ghidra.app.nav.Navigatable; import ghidra.app.nav.Navigatable;
import ghidra.app.util.viewer.format.ErrorListingField;
import ghidra.framework.plugintool.ServiceProvider; import ghidra.framework.plugintool.ServiceProvider;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.util.Msg; import ghidra.util.Msg;
@@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package ghidra.app.util.viewer.format; package ghidra.app.util.viewer.field;
import java.awt.Color; import java.awt.Color;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.*; import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.Highlight;
import generic.theme.GColor; import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors; import generic.theme.GThemeDefaults.Colors;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.*;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
public class ErrorListingField extends ListingTextField { public class ErrorListingField extends ListingTextField {
@@ -31,21 +31,25 @@ public class ErrorListingField extends ListingTextField {
private Throwable t; private Throwable t;
private static HighlightProvider myProvider = private static ListingHighlightProvider myProvider =
(text, obj, fieldFactoryClass, cursorTextOffset) -> new Highlight[] { (text, field, cursorTextOffset) -> new Highlight[] {
new Highlight(0, text.length() - 1, BG_ERROR_COLOR) }; new Highlight(0, text.length() - 1, BG_ERROR_COLOR) };
public ErrorListingField(FieldFactory ff, ProxyObj<?> proxy, int varWidth, Throwable t) { public ErrorListingField(FieldFactory ff, ProxyObj<?> proxy, int varWidth, Throwable t) {
super(ff, proxy, createField(ff, proxy, varWidth, t)); super(ff, proxy, null, createHighlightFactory());
this.field = createField(ff, proxy, varWidth);
this.t = t; this.t = t;
} }
private static TextField createField(FieldFactory ff, ProxyObj<?> proxy, int varWidth, private static ListingFieldHighlightFactoryAdapter createHighlightFactory() {
Throwable t) { return new ListingFieldHighlightFactoryAdapter(myProvider);
HighlightFactory hlFactory = }
new FieldHighlightFactory(myProvider, ff.getClass(), proxy.getObject());
return new ClippingTextField(ff.getStartX() + varWidth, ff.getWidth(), private ClippingTextField createField(FieldFactory ff, ProxyObj<?> proxy, int varWidth) {
createElement(ff, t), hlFactory); ClippingTextField textField =
new ClippingTextField(ff.getStartX() + varWidth, ff.getWidth(),
createElement(ff, t), hlFactory);
return textField;
} }
private static FieldElement createElement(FieldFactory ff, Throwable t) { private static FieldElement createElement(FieldFactory ff, Throwable t) {
@@ -20,7 +20,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.Gui; import generic.theme.Gui;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.template.TemplateSimplifier; import ghidra.app.util.template.TemplateSimplifier;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@@ -51,7 +51,7 @@ public abstract class FieldFactory implements ExtensionPoint {
protected Font baseFont; protected Font baseFont;
protected int style = -1; protected int style = -1;
protected boolean enabled = true; protected boolean enabled = true;
protected HighlightProvider hlProvider; protected ListingHighlightProvider hlProvider;
protected String colorOptionName; protected String colorOptionName;
protected String styleOptionName; protected String styleOptionName;
@@ -65,7 +65,8 @@ public abstract class FieldFactory implements ExtensionPoint {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
protected FieldFactory(String name, FieldFormatModel model, HighlightProvider highlightProvider, protected FieldFactory(String name, FieldFormatModel model,
ListingHighlightProvider highlightProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
this.name = name; this.name = name;
this.model = model; this.model = model;
@@ -81,7 +82,7 @@ public abstract class FieldFactory implements ExtensionPoint {
protected void initFieldOptions(Options fieldOptions) { protected void initFieldOptions(Options fieldOptions) {
fieldOptions.getOptions(name) fieldOptions.getOptions(name)
.setOptionsHelpLocation(new HelpLocation("CodeBrowserPlugin", name)); .setOptionsHelpLocation(new HelpLocation("CodeBrowserPlugin", name));
} }
protected void initDisplayOptions(Options displayOptions) { protected void initDisplayOptions(Options displayOptions) {
@@ -121,7 +122,8 @@ public abstract class FieldFactory implements ExtensionPoint {
* @return the factory * @return the factory
*/ */
public abstract FieldFactory newInstance(FieldFormatModel formatModel, public abstract FieldFactory newInstance(FieldFormatModel formatModel,
HighlightProvider highlightProvider, ToolOptions options, ToolOptions fieldOptions); ListingHighlightProvider highlightProvider, ToolOptions options,
ToolOptions fieldOptions);
/** /**
* Notifications that the display options changed. * Notifications that the display options changed.
@@ -220,6 +222,19 @@ public abstract class FieldFactory implements ExtensionPoint {
model.modelChanged(); model.modelChanged();
} }
/**
* Returns true if this given field represents the given location
* @param listingField the field
* @param location the location
* @return true if this given field represents the given location
*/
public boolean supportsLocation(ListingField listingField, ProgramLocation location) {
BigInteger dummyIndex = BigInteger.ZERO;
int dummyFieldNumber = 0;
FieldLocation f = getFieldLocation(listingField, dummyIndex, dummyFieldNumber, location);
return f != null;
}
/** /**
* Generates a Field based on the given information. * Generates a Field based on the given information.
* @param obj The object that the generated field will report some information about. * @param obj The object that the generated field will report some information about.
@@ -1,51 +0,0 @@
/* ###
* IP: GHIDRA
*
* 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.
*/
package ghidra.app.util.viewer.field;
import docking.widgets.fieldpanel.field.Field;
import docking.widgets.fieldpanel.support.Highlight;
import docking.widgets.fieldpanel.support.HighlightFactory;
import ghidra.app.util.HighlightProvider;
/**
* Wrapper class to hold field factory information in the text field to be provided to the
* highlightProvider to get highlights just before the field is painted.
*
*/
public class FieldHighlightFactory implements HighlightFactory {
private HighlightProvider provider;
private Class<? extends FieldFactory> fieldFactoryClass;
private Object obj;
/**
* Constructs a new FieldHighlightFactory.
* @param provider the HighlightProvider that will actually compute the highlights.
* @param fieldFactoryClass the class of the field factory that generated the field to be rendered.
* @param obj the object that holds the information that will be rendered (usually a code unit)
*/
public FieldHighlightFactory(HighlightProvider provider,
Class<? extends FieldFactory> fieldFactoryClass, Object obj) {
this.provider = provider;
this.fieldFactoryClass = fieldFactoryClass;
this.obj = obj;
}
@Override
public Highlight[] getHighlights(Field field, String text, int cursorTextOffset) {
return provider.getHighlights(text, obj, fieldFactoryClass, cursorTextOffset);
}
}
@@ -20,7 +20,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.GhidraOptions; import ghidra.GhidraOptions;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.format.FormatManager; import ghidra.app.util.viewer.format.FormatManager;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@@ -70,7 +70,7 @@ public class FieldNameFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private FieldNameFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private FieldNameFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, ToolOptions fieldOptions) { Options displayOptions, ToolOptions fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
fieldOptions.registerOption(ARRAY_INDEX_FORMAT_NAME, IndexFormat.decimal, null, fieldOptions.registerOption(ARRAY_INDEX_FORMAT_NAME, IndexFormat.decimal, null,
@@ -155,7 +155,7 @@ public class FieldNameFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new FieldNameFieldFactory(formatModel, provider, toolOptions, fieldOptions); return new FieldNameFieldFactory(formatModel, provider, toolOptions, fieldOptions);
} }
@@ -21,7 +21,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GColor; import generic.theme.GColor;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.*; import ghidra.framework.options.*;
@@ -66,7 +66,7 @@ public class FileOffsetFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private FileOffsetFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private FileOffsetFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
initOptions(fieldOptions); initOptions(fieldOptions);
@@ -97,7 +97,7 @@ public class FileOffsetFieldFactory extends FieldFactory {
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, public FieldFactory newInstance(FieldFormatModel formatModel,
HighlightProvider highlightProvider, ToolOptions options, ToolOptions fieldOptions) { ListingHighlightProvider highlightProvider, ToolOptions options, ToolOptions fieldOptions) {
return new FileOffsetFieldFactory(formatModel, highlightProvider, options, fieldOptions); return new FileOffsetFieldFactory(formatModel, highlightProvider, options, fieldOptions);
} }
@@ -20,7 +20,7 @@ import java.util.ArrayList;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.FunctionColors; import ghidra.app.util.viewer.field.ListingColors.FunctionColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.FunctionProxy; import ghidra.app.util.viewer.proxy.FunctionProxy;
@@ -52,7 +52,7 @@ public class FunctionCallFixupFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
public FunctionCallFixupFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, public FunctionCallFixupFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
@@ -118,7 +118,7 @@ public class FunctionCallFixupFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
return new FunctionCallFixupFieldFactory(formatModel, provider, displayOptions, return new FunctionCallFixupFieldFactory(formatModel, provider, displayOptions,
fieldOptions); fieldOptions);
@@ -20,7 +20,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GColor; import generic.theme.GColor;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
import ghidra.framework.options.Options; import ghidra.framework.options.Options;
@@ -37,14 +37,14 @@ public class FunctionPurgeFieldFactory extends FieldFactory {
super(FIELD_NAME); super(FIELD_NAME);
} }
private FunctionPurgeFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private FunctionPurgeFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel newModel, HighlightProvider newHlProvider, public FieldFactory newInstance(FieldFormatModel newModel, ListingHighlightProvider newHlProvider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new FunctionPurgeFieldFactory(newModel, newHlProvider, toolOptions, fieldOptions); return new FunctionPurgeFieldFactory(newModel, newHlProvider, toolOptions, fieldOptions);
} }
@@ -21,7 +21,7 @@ import docking.widgets.fieldpanel.field.AttributedString;
import docking.widgets.fieldpanel.field.FieldElement; import docking.widgets.fieldpanel.field.FieldElement;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import generic.theme.GColor; import generic.theme.GColor;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.CommentColors; import ghidra.app.util.viewer.field.ListingColors.CommentColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.FunctionProxy; import ghidra.app.util.viewer.proxy.FunctionProxy;
@@ -55,7 +55,7 @@ public class FunctionRepeatableCommentFieldFactory extends FieldFactory {
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
public FunctionRepeatableCommentFieldFactory(FieldFormatModel model, public FunctionRepeatableCommentFieldFactory(FieldFormatModel model,
HighlightProvider hlProvider, Options displayOptions, Options fieldOptions) { ListingHighlightProvider hlProvider, Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@@ -121,7 +121,7 @@ public class FunctionRepeatableCommentFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions options, ToolOptions fieldOptions) { ToolOptions options, ToolOptions fieldOptions) {
return new FunctionRepeatableCommentFieldFactory(formatModel, provider, options, return new FunctionRepeatableCommentFieldFactory(formatModel, provider, options,
@@ -24,7 +24,7 @@ import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import docking.widgets.fieldpanel.support.RowColLocation; import docking.widgets.fieldpanel.support.RowColLocation;
import ghidra.GhidraOptions; import ghidra.GhidraOptions;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.FunctionColors; import ghidra.app.util.viewer.field.ListingColors.FunctionColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.FunctionProxy; import ghidra.app.util.viewer.proxy.FunctionProxy;
@@ -58,7 +58,7 @@ public class FunctionSignatureFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
public FunctionSignatureFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, public FunctionSignatureFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
@@ -374,7 +374,7 @@ public class FunctionSignatureFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new FunctionSignatureFieldFactory(formatModel, provider, toolOptions, fieldOptions); return new FunctionSignatureFieldFactory(formatModel, provider, toolOptions, fieldOptions);
} }
@@ -20,7 +20,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.AttributedString; import docking.widgets.fieldpanel.field.AttributedString;
import docking.widgets.fieldpanel.field.TextFieldElement; import docking.widgets.fieldpanel.field.TextFieldElement;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.FunctionColors; import ghidra.app.util.viewer.field.ListingColors.FunctionColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.FunctionProxy; import ghidra.app.util.viewer.proxy.FunctionProxy;
@@ -55,7 +55,7 @@ public class FunctionSignatureSourceFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
public FunctionSignatureSourceFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, public FunctionSignatureSourceFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@@ -112,7 +112,7 @@ public class FunctionSignatureSourceFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new FunctionSignatureSourceFieldFactory(formatModel, provider, toolOptions, return new FunctionSignatureSourceFieldFactory(formatModel, provider, toolOptions,
fieldOptions); fieldOptions);
@@ -23,7 +23,7 @@ import org.apache.commons.lang3.StringUtils;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.FunctionColors; import ghidra.app.util.viewer.field.ListingColors.FunctionColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.FunctionProxy; import ghidra.app.util.viewer.proxy.FunctionProxy;
@@ -59,7 +59,7 @@ public class FunctionTagFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private FunctionTagFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private FunctionTagFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
} }
@@ -125,7 +125,7 @@ public class FunctionTagFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new FunctionTagFieldFactory(formatModel, provider, toolOptions, fieldOptions); return new FunctionTagFieldFactory(formatModel, provider, toolOptions, fieldOptions);
} }
@@ -21,7 +21,6 @@ import javax.swing.Icon;
import docking.widgets.fieldpanel.field.SimpleImageField; import docking.widgets.fieldpanel.field.SimpleImageField;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.EmptyProxy; import ghidra.app.util.viewer.proxy.EmptyProxy;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@@ -79,11 +78,6 @@ public class ImageFactoryField extends SimpleImageField implements ListingField
return factory; return factory;
} }
@Override
public FieldFormatModel getFieldModel() {
return factory.getFieldModel();
}
@Override @Override
public ProxyObj<?> getProxy() { public ProxyObj<?> getProxy() {
if (proxy == null) { if (proxy == null) {
@@ -23,7 +23,6 @@ import docking.widgets.fieldpanel.internal.FieldBackgroundColorManager;
import docking.widgets.fieldpanel.internal.PaintContext; import docking.widgets.fieldpanel.internal.PaintContext;
import docking.widgets.fieldpanel.support.*; import docking.widgets.fieldpanel.support.*;
import generic.theme.GThemeDefaults.Colors.Palette; import generic.theme.GThemeDefaults.Colors.Palette;
import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.EmptyProxy; import ghidra.app.util.viewer.proxy.EmptyProxy;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@@ -80,15 +79,6 @@ public class IndentField implements ListingField {
return factory; return factory;
} }
/**
* Returns the FieldModel that contains the FieldFactory that generated this
* field.
*/
@Override
public FieldFormatModel getFieldModel() {
return factory.getFieldModel();
}
/** /**
* Returns the object associated with this field instance. * Returns the object associated with this field instance.
*/ */
@@ -20,7 +20,7 @@ import java.math.BigInteger;
import docking.widgets.fieldpanel.field.*; import docking.widgets.fieldpanel.field.*;
import docking.widgets.fieldpanel.support.FieldLocation; import docking.widgets.fieldpanel.support.FieldLocation;
import ghidra.app.util.HighlightProvider; import ghidra.app.util.ListingHighlightProvider;
import ghidra.app.util.viewer.field.ListingColors.MaskColors; import ghidra.app.util.viewer.field.ListingColors.MaskColors;
import ghidra.app.util.viewer.format.FieldFormatModel; import ghidra.app.util.viewer.format.FieldFormatModel;
import ghidra.app.util.viewer.proxy.ProxyObj; import ghidra.app.util.viewer.proxy.ProxyObj;
@@ -52,7 +52,7 @@ public class InstructionMaskValueFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private InstructionMaskValueFieldFactory(FieldFormatModel model, HighlightProvider hsProvider, private InstructionMaskValueFieldFactory(FieldFormatModel model, ListingHighlightProvider hsProvider,
Options displayOptions, Options fieldOptions) { Options displayOptions, Options fieldOptions) {
super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hsProvider, displayOptions, fieldOptions);
} }
@@ -165,7 +165,7 @@ public class InstructionMaskValueFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider hsProvider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider hsProvider,
ToolOptions toolOptions, ToolOptions fieldOptions) { ToolOptions toolOptions, ToolOptions fieldOptions) {
return new InstructionMaskValueFieldFactory(formatModel, hsProvider, toolOptions, return new InstructionMaskValueFieldFactory(formatModel, hsProvider, toolOptions,
fieldOptions); fieldOptions);
@@ -83,7 +83,7 @@ public class LabelFieldFactory extends FieldFactory {
* @param displayOptions the Options for display properties. * @param displayOptions the Options for display properties.
* @param fieldOptions the Options for field specific properties. * @param fieldOptions the Options for field specific properties.
*/ */
private LabelFieldFactory(FieldFormatModel model, HighlightProvider hlProvider, private LabelFieldFactory(FieldFormatModel model, ListingHighlightProvider hlProvider,
ToolOptions displayOptions, ToolOptions fieldOptions) { ToolOptions displayOptions, ToolOptions fieldOptions) {
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions); super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
@@ -449,7 +449,7 @@ public class LabelFieldFactory extends FieldFactory {
} }
@Override @Override
public FieldFactory newInstance(FieldFormatModel formatModel, HighlightProvider provider, public FieldFactory newInstance(FieldFormatModel formatModel, ListingHighlightProvider provider,
ToolOptions pDisplayOptions, ToolOptions fieldOptions) { ToolOptions pDisplayOptions, ToolOptions fieldOptions) {
return new LabelFieldFactory(formatModel, provider, pDisplayOptions, fieldOptions); return new LabelFieldFactory(formatModel, provider, pDisplayOptions, fieldOptions);
} }

Some files were not shown because too many files have changed in this diff Show More