Merge remote-tracking branch

'origin/GP-1374-dragonmacher-sort-exported-enum-values--SQUASHED'
(Closes #1664)
This commit is contained in:
Ryan Kurtz 2021-10-13 11:31:35 -04:00
commit 353a85e4fd
8 changed files with 225 additions and 108 deletions

View file

@ -30,7 +30,6 @@ import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.task.TaskMonitor;
import ghidra.util.task.TaskMonitorAdapter;
import ghidra.util.xml.*;
import ghidra.xml.*;
@ -245,7 +244,7 @@ public class DataTypesXmlMgr {
private boolean processEnum(XmlTreeNode root) {
XmlElement element = root.getStartElement();
String name = element.getAttribute("NAME");
String comment = getRegularComment(root);
String enuumComment = getRegularComment(root);
CategoryPath cp = getCategoryPath(element);
int size = XmlUtilities.parseInt(element.getAttribute("SIZE"), defaultEnumSize);
@ -257,9 +256,10 @@ public class DataTypesXmlMgr {
XmlElement childElement = node.getStartElement();
String entryName = childElement.getAttribute("NAME");
long entryValue = XmlUtilities.parseLong(childElement.getAttribute("VALUE"));
enuum.add(entryName, entryValue);
String comment = childElement.getAttribute("COMMENT");
enuum.add(entryName, entryValue, comment);
}
enuum.setDescription(comment);
enuum.setDescription(enuumComment);
dataManager.addDataType(enuum, null);
return true;
}
@ -288,6 +288,7 @@ public class DataTypesXmlMgr {
td.setCategoryPath(cp);
}
catch (DuplicateNameException e) {
log.appendMsg("Unable to place typedef '" + name + "' in category '" + cp + "'");
}
dataManager.addDataType(td, null);
@ -546,11 +547,11 @@ public class DataTypesXmlMgr {
writeRegularComment(writer, enuum.getDescription());
String[] names = enuum.getNames();
Arrays.sort(names);
for (String name : names) {
attrs = new XmlAttributes();
attrs.addAttribute("NAME", name);
attrs.addAttribute("VALUE", enuum.getValue(name), true);
attrs.addAttribute("COMMENT", enuum.getComment(name));
writer.startElement("ENUM_ENTRY", attrs);
writer.endElement("ENUM_ENTRY");
}
@ -666,8 +667,8 @@ public class DataTypesXmlMgr {
/**
* Output data types in XML format for debugging purposes.
* NOTE: There is no support for reading the XML produced by this
* method.
* NOTE: There is no support for reading the XML produced by this method.
* @param dataManager the data type manager
* @param outputFilename name of the output file
* @throws IOException if there was a problem writing to the file
*/
@ -683,9 +684,10 @@ public class DataTypesXmlMgr {
MessageLog log = new MessageLog();
DataTypesXmlMgr mgr = new DataTypesXmlMgr(dataManager, log);
try {
mgr.write(writer, TaskMonitorAdapter.DUMMY_MONITOR);
mgr.write(writer, TaskMonitor.DUMMY);
}
catch (CancelledException e) {
// can't happen with dummy monitor
}
writer.close();

View file

@ -29,7 +29,7 @@ import ghidra.program.model.data.Enum;
import ghidra.program.model.data.EnumDataType;
import ghidra.program.util.ChangeManager;
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
import ghidra.util.task.TaskMonitorAdapter;
import ghidra.util.task.TaskMonitor;
/**
* Tests for Enum data types.
@ -40,10 +40,6 @@ public class EnumTest extends AbstractGhidraHeadedIntegrationTest {
private DataTypeManagerDB dataMgr;
private int transactionID;
public EnumTest() {
super();
}
@Before
public void setUp() throws Exception {
program = createDefaultProgram("Test", ProgramBuilder._TOY, this);
@ -223,7 +219,7 @@ public class EnumTest extends AbstractGhidraHeadedIntegrationTest {
Enum enummDT = (Enum) dataMgr.resolve(enumm, null);
assertNotNull(enummDT);
c.remove(enummDT, TaskMonitorAdapter.DUMMY_MONITOR);
c.remove(enummDT, TaskMonitor.DUMMY);
assertNull(c.getDataType("Color"));
assertTrue(enummDT.isDeleted());
@ -294,6 +290,7 @@ public class EnumTest extends AbstractGhidraHeadedIntegrationTest {
Assert.fail("Should have gotten no such element exception!");
}
catch (NoSuchElementException e) {
// expected
}
}
@ -335,27 +332,56 @@ public class EnumTest extends AbstractGhidraHeadedIntegrationTest {
myEnum.add("Green", 15);
myEnum.add("Blue", 20);
assertTrue(enummDT.isEquivalent(myEnum));
}
@Test
public void testNameSort() {
Enum myEnum = new EnumDataType("Color", 1);
myEnum.add("Red", 1);
myEnum.add("Green", 5);
myEnum.add("Blue", 10);
String[] names = myEnum.getNames();
assertEquals("Red", names[0]);
assertEquals("Green", names[1]);
assertEquals("Blue", names[2]);
myEnum = new EnumDataType("Color", 1);
myEnum.add("Red", 20);
myEnum.add("Green", 1);
myEnum.add("Blue", 3);
names = myEnum.getNames();
assertEquals("Green", names[0]);
assertEquals("Blue", names[1]);
assertEquals("Red", names[2]);
// multiple names per value, requires sub-sorting
myEnum = new EnumDataType("Color", 1);
myEnum.add("Red", 20);
myEnum.add("Pink", 20);
myEnum.add("Salmon", 20);
myEnum.add("Green", 1);
myEnum.add("AnotherGreen", 1);
myEnum.add("Blue", 3);
names = myEnum.getNames();
assertEquals("AnotherGreen", names[0]);
assertEquals("Green", names[1]);
assertEquals("Blue", names[2]);
assertEquals("Pink", names[3]);
assertEquals("Red", names[4]);
assertEquals("Salmon", names[5]);
}
private void waitForListenerCount(DomainObjListener listener, int count) {
int cnt = 0;
try {
while (cnt++ < 10 && listener.getCount() != count) {
Thread.sleep(100);
}
Thread.sleep(300);
}
catch (InterruptedException e) {
}
waitForCondition(() -> listener.getCount() == count);
}
private class DomainObjListener implements DomainObjectListener {
private int count;
/* (non-Javadoc)
* @see ghidra.framework.model.DomainObjectListener#domainObjectChanged(ghidra.framework.model.DomainObjectChangedEvent)
*/
@Override
public void domainObjectChanged(DomainObjectChangedEvent ev) {
for (int i = 0; i < ev.numRecords(); i++) {