Merge remote-tracking branch 'origin/GP-3715_ghizard_PDB_perf_investigate_resolve_as_you_go_squash_and_rebase20231101'

This commit is contained in:
Ryan Kurtz 2023-11-28 11:59:10 -05:00
commit d4861c46ac
46 changed files with 2587 additions and 3253 deletions

View file

@ -16,17 +16,24 @@
// Text-dump all data types from the user-specified DataTypeManager to the user-specified file.
//
//@category Data Types
import java.awt.*;
import java.io.File;
import java.io.FileWriter;
import java.util.Iterator;
import javax.swing.JLabel;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.text.View;
import docking.widgets.OptionDialog;
import generic.text.TextLayoutGraphics;
import ghidra.app.script.GhidraScript;
import ghidra.app.services.DataTypeManagerService;
import ghidra.app.util.ToolTipUtils;
import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.data.*;
import ghidra.util.*;
import ghidra.util.Msg;
import ghidra.util.Swing;
import ghidra.util.exception.CancelledException;
public class DeveloperDumpAllTypesScript extends GhidraScript {
@ -62,7 +69,7 @@ public class DeveloperDumpAllTypesScript extends GhidraScript {
String pathString = dataTypePath.toString();
String htmlString = ToolTipUtils.getToolTipText(dataType);
String plainString = Swing.runNow(() -> {
return HTMLUtilities.fromHTML(htmlString);
return fromHTML(htmlString);
});
fileWriter.append(pathString);
fileWriter.append("\n");
@ -77,6 +84,100 @@ public class DeveloperDumpAllTypesScript extends GhidraScript {
Msg.info(this, message);
}
// Method below copied from HTMLUtilities and modified to set a fixed size so that it
// is consistent between runs between tools over the course of time.
/**
* Checks the given string to see it is HTML, according to {@link BasicHTML} and then
* will return the text without any markup tags if it is.
*
* @param text the text to convert
* @return the converted String
*/
private static String fromHTML(String text) {
if (text == null) {
return null;
}
if (!BasicHTML.isHTMLString(text)) {
// the message may still contain HTML, but that is something we don't handle
return text;
}
//
// Use the label's builtin handling of HTML text via the HTMLEditorKit
//
Swing.assertSwingThread("This method must be called on the Swing thread");
JLabel label = new JLabel(text) {
@Override
public void paint(Graphics g) {
// we cannot use paint, as we are not parented; change paint to call
// something that works
super.paintComponent(g);
}
};
View v = (View) label.getClientProperty(BasicHTML.propertyKey);
if (v == null) {
return text;
}
//
// Use some magic to turn the painting into text
//
//Dimension size = label.getPreferredSize();
Dimension size = new Dimension(500, 500);
label.setBounds(new Rectangle(0, 0, size.width, size.height));
// Note: when laying out an unparented label, the y value will be half of the height
Rectangle bounds =
new Rectangle(-size.width, -size.height, size.width * 2, size.height * 10);
TextLayoutGraphics g = new TextLayoutGraphics();
g.setClip(bounds);
label.paint(g);
g.flush();
String raw = g.getBuffer();
raw = raw.trim(); // I can't see any reason to keep leading/trailing newlines/whitespace
String updated = replaceKnownSpecialCharacters(raw);
//
// Unfortunately, the label adds odd artifacts to the output, like newlines after
// formatting tags (like <B>, <FONT>, etc). So, just normalize the text, not
// preserving any of the line breaks.
//
// Note: Calling this method here causes unwanted removal of newlines. If the original
// need for this call is found, this can be revisited.
// (see history for condense() code)
// String condensed = condense(updated);
return updated;
}
// Copied from HTMLUtilities
/**
* A method to remove characters from the given string that are output by the HTML
* conversion process when going from HTML to plain text.
*
* @param s the string to be updated
* @return the updated String
*/
private static String replaceKnownSpecialCharacters(String s) {
StringBuilder buffy = new StringBuilder();
s.chars().forEach(c -> {
switch (c) {
case 0xA0:
buffy.append((char) 0x20);
break;
default:
buffy.append((char) c);
}
});
return buffy.toString();
}
private DataTypeManager userChooseDataTypeManager() {
PluginTool tool = state.getTool();
DataTypeManagerService service = tool.getService(DataTypeManagerService.class);