diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileOptions.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileOptions.java index 53abe316d3..d66089ecc6 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileOptions.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileOptions.java @@ -209,7 +209,7 @@ public class DecompileOptions { private final static boolean CONVENTION_OPTIONDEFAULT = true; // Must match PrintC::resetDefaultsPrintC private boolean conventionPrint; - private final static String NOCAST_OPTIONSTRING = "Display.Disable printing of type casts"; + public final static String NOCAST_OPTIONSTRING = "Display.Disable printing of type casts"; private final static String NOCAST_OPTIONDESCRIPTION = "If set, any C style type cast recovered by the decompiler will not be displayed. " + "The resulting C syntax may not parse correctly."; diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilePlugin.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilePlugin.java index 4ffc346ec5..ad27c3ae85 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilePlugin.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilePlugin.java @@ -61,6 +61,8 @@ import ghidra.util.task.SwingUpdateManager; //@formatter:on public class DecompilePlugin extends Plugin { + public static final String OPTIONS_TITLE = "Decompiler"; + private PrimaryDecompilerProvider connectedProvider; private List disconnectedProviders; diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilerProvider.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilerProvider.java index fef5e719e0..65e25e3082 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilerProvider.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DecompilerProvider.java @@ -60,8 +60,6 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter implements OptionsChangeListener, DecompilerCallbackHandler, DecompilerHighlightService, DecompilerMarginService { - private static final String OPTIONS_TITLE = "Decompiler"; - private static final Icon REFRESH_ICON = Icons.REFRESH_ICON; private static final Icon C_SOURCE_ICON = new GIcon("icon.decompiler.action.provider"); @@ -199,7 +197,7 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter public void componentShown() { if (program != null && currentLocation != null) { ToolOptions fieldOptions = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_FIELDS); - ToolOptions opt = tool.getOptions(OPTIONS_TITLE); + ToolOptions opt = tool.getOptions(DecompilePlugin.OPTIONS_TITLE); decompilerOptions.grabFromToolAndProgram(fieldOptions, opt, program); controller.setOptions(decompilerOptions); @@ -313,7 +311,7 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter return; } ToolOptions fieldOptions = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_FIELDS); - ToolOptions opt = tool.getOptions(OPTIONS_TITLE); + ToolOptions opt = tool.getOptions(DecompilePlugin.OPTIONS_TITLE); // Current values of toggle buttons boolean decompilerEliminatesUnreachable = decompilerOptions.isEliminateUnreachable(); @@ -369,7 +367,7 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter return; } - if (options.getName().equals(OPTIONS_TITLE) || + if (options.getName().equals(DecompilePlugin.OPTIONS_TITLE) || options.getName().equals(GhidraOptions.CATEGORY_BROWSER_FIELDS)) { doRefresh(true); } @@ -420,7 +418,7 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter if (program != null) { program.addListener(programListener); ToolOptions fieldOptions = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_FIELDS); - ToolOptions opt = tool.getOptions(OPTIONS_TITLE); + ToolOptions opt = tool.getOptions(DecompilePlugin.OPTIONS_TITLE); decompilerOptions.grabFromToolAndProgram(fieldOptions, opt, program); } @@ -767,7 +765,7 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter private void initializeDecompilerOptions() { ToolOptions fieldOptions = tool.getOptions(GhidraOptions.CATEGORY_BROWSER_FIELDS); - ToolOptions opt = tool.getOptions(OPTIONS_TITLE); + ToolOptions opt = tool.getOptions(DecompilePlugin.OPTIONS_TITLE); HelpLocation helpLocation = new HelpLocation(HelpTopics.DECOMPILER, "GeneralOptions"); opt.setOptionsHelpLocation(helpLocation); opt.getOptions("Analysis") @@ -1129,6 +1127,7 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter CloneDecompilerAction cloneDecompilerAction = new CloneDecompilerAction(); GoToNextBraceAction goToNextBraceAction = new GoToNextBraceAction(); GoToPreviousBraceAction goToPreviousBraceAction = new GoToPreviousBraceAction(); + DisplayTypeCastsAction displayTypeCastsAction = new DisplayTypeCastsAction(plugin); addLocalAction(refreshAction); addLocalAction(displayUnreachableCodeToggle); @@ -1178,6 +1177,7 @@ public class DecompilerProvider extends NavigatableComponentProviderAdapter addLocalAction(renameLabelAction); addLocalAction(removeLabelAction); addLocalAction(debugFunctionAction); + addLocalAction(displayTypeCastsAction); addLocalAction(convertAction); addLocalAction(findAction); addLocalAction(findReferencesAction); diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DisplayTypeCastsAction.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DisplayTypeCastsAction.java new file mode 100644 index 0000000000..681eb61810 --- /dev/null +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/DisplayTypeCastsAction.java @@ -0,0 +1,87 @@ +/* ### + * 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.plugin.core.decompile; + +import docking.ActionContext; +import docking.action.*; +import ghidra.app.decompiler.DecompileOptions; +import ghidra.app.util.HelpTopics; +import ghidra.framework.options.OptionsChangeListener; +import ghidra.framework.options.ToolOptions; +import ghidra.framework.plugintool.PluginTool; +import ghidra.util.HelpLocation; +import ghidra.util.bean.opteditor.OptionsVetoException; + +/** + * An action to update the Decompiler option for disabling the display of type casts. + */ +public class DisplayTypeCastsAction extends ToggleDockingAction { + + private DecompilePlugin plugin; + private OptionsChangeListener listener = new DisplayTypeCastsOptionsListener(); + + protected DisplayTypeCastsAction(DecompilePlugin plugin) { + super("Disable Type Casts Display", plugin.getClass().getSimpleName()); + this.plugin = plugin; + + setHelpLocation(new HelpLocation(HelpTopics.DECOMPILER, "DisplayDisableCasts")); + setKeyBindingData(new KeyBindingData("BACK_SLASH")); + + // the menu group 'wDebug' is just above 'Debug Function Decompilation' + setMenuBarData(new MenuData(new String[] { "Disable Type Casts" }, "wDebug")); + + PluginTool tool = plugin.getTool(); + ToolOptions options = tool.getOptions(DecompilePlugin.OPTIONS_TITLE); + boolean disableTypeCasts = options.getBoolean(DecompileOptions.NOCAST_OPTIONSTRING, false); + setEnabled(disableTypeCasts); + + options.addOptionsChangeListener(listener); + } + + @Override + public boolean isEnabledForContext(ActionContext context) { + return true; + } + + @Override + public void actionPerformed(ActionContext context) { + PluginTool tool = plugin.getTool(); + ToolOptions options = tool.getOptions(DecompilePlugin.OPTIONS_TITLE); + options.setBoolean(DecompileOptions.NOCAST_OPTIONSTRING, isSelected()); + } + + private class DisplayTypeCastsOptionsListener implements OptionsChangeListener { + + @Override + public void optionsChanged(ToolOptions options, String optionName, Object oldValue, + Object newValue) throws OptionsVetoException { + + if (DecompileOptions.NOCAST_OPTIONSTRING.equals(optionName)) { + Boolean optionSelected = (Boolean) newValue; + if (isSelected() != optionSelected) { + setSelected(optionSelected); + } + } + } + } + + @Override + public void dispose() { + PluginTool tool = plugin.getTool(); + ToolOptions options = tool.getOptions(DecompilePlugin.OPTIONS_TITLE); + options.removeOptionsChangeListener(listener); + } +}