mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Candidate release of source code.
This commit is contained in:
parent
db81e6b3b0
commit
79d8f164f8
12449 changed files with 2800756 additions and 16 deletions
|
@ -0,0 +1,49 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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.pcodeCPort.slgh_compile.regression;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
||||
public class PushbackEntireLine {
|
||||
private final BufferedReader reader;
|
||||
private String line = null;
|
||||
|
||||
public PushbackEntireLine(BufferedReader reader) {
|
||||
this.reader = reader;
|
||||
}
|
||||
|
||||
public synchronized String readLine() throws IOException {
|
||||
if (line != null) {
|
||||
String tmp = line;
|
||||
line = null;
|
||||
return tmp;
|
||||
}
|
||||
return reader.readLine();
|
||||
}
|
||||
|
||||
public synchronized void putbackLine(String pushedLine) throws IOException {
|
||||
if (line != null) {
|
||||
throw new IOException("can only putback one line");
|
||||
}
|
||||
line = pushedLine;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
reader.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,272 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* NOTE: The presence of the MIPS and 8051 path flags beg the question: what OTHER languages besides what we know about need these defines?
|
||||
*
|
||||
* 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.pcodeCPort.slgh_compile.regression;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.antlr.runtime.RecognitionException;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jdom.JDOMException;
|
||||
import org.junit.*;
|
||||
import org.junit.experimental.categories.Category;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import generic.test.AbstractGenericTest;
|
||||
import generic.test.category.NightlyCategory;
|
||||
import ghidra.framework.*;
|
||||
import ghidra.pcodeCPort.slgh_compile.SleighCompileLauncher;
|
||||
|
||||
@Category(NightlyCategory.class)
|
||||
public class SleighCompileRegressionTest extends AbstractGenericTest {
|
||||
private static final int TOO_MANY_ERRORS = 100;
|
||||
|
||||
private Logger log;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
log = LogManager.getLogger(SleighCompileRegressionTest.class);
|
||||
}
|
||||
|
||||
private boolean allOK = true;
|
||||
private int currentLangBadCount;
|
||||
|
||||
private boolean itsOK(String message, boolean condition) {
|
||||
if (!condition) {
|
||||
++currentLangBadCount;
|
||||
if (currentLangBadCount <= TOO_MANY_ERRORS + 1) {
|
||||
log.fatal(message);
|
||||
}
|
||||
allOK = false;
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExternal() throws Exception {
|
||||
|
||||
StringBuffer summary = new StringBuffer();
|
||||
|
||||
LoggingInitialization.initializeLoggingSystem();
|
||||
List<ResourceFile> inputs = getSlaspecFiles();
|
||||
Iterator<ResourceFile> ii = inputs.iterator();
|
||||
|
||||
while (ii.hasNext()) {
|
||||
ResourceFile inputFile = ii.next();
|
||||
String inputName = inputFile.getName().replaceFirst("\\.slaspec$", "-");
|
||||
File targetFile = createTempFile("target-" + inputName, ".sla");
|
||||
File actualFile = createTempFile("actual-" + inputName, ".sla");
|
||||
log.info("testing " + inputFile + " (in " + targetFile + " and " + actualFile + ")");
|
||||
|
||||
int targetRetval = runTargetCompiler(inputFile, targetFile);
|
||||
if (itsOK("non-zero target compiler return value", 0 == targetRetval)) {
|
||||
|
||||
int actualRetval = runActualCompiler(inputFile.getFile(false), actualFile);
|
||||
if (itsOK("non-zero actual compiler return value", 0 == actualRetval)) {
|
||||
currentLangBadCount = 0;
|
||||
boolean ok = comparesOK(actualFile, targetFile);
|
||||
|
||||
if (ok) {
|
||||
assertTrue("could not delete target output file " + targetFile,
|
||||
targetFile.delete());
|
||||
assertTrue("could not delete actual output file " + actualFile,
|
||||
actualFile.delete());
|
||||
}
|
||||
else {
|
||||
summary.append("Sleigh compile mismatch for: " + inputFile + "\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
summary.append("Sleigh(Java) compile failed for: " + inputFile + "\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
summary.append("Sleigh(C) compile failed for: " + inputFile + "\n");
|
||||
}
|
||||
// printMemory();
|
||||
}
|
||||
if (allOK) {
|
||||
log.info("SUCCESS! Finished all tests.");
|
||||
}
|
||||
else {
|
||||
log.error("FAILURE. Look in the log above for Sleigh ERROR messages\n" + summary);
|
||||
Assert.fail("Sleigh language errors found");
|
||||
}
|
||||
}
|
||||
|
||||
private int runTargetCompiler(ResourceFile inputFile, File targetFile)
|
||||
throws IOException, InterruptedException {
|
||||
String command = getCppSleighCompilerForArch();
|
||||
ProcessBuilder processBuilder =
|
||||
new ProcessBuilder(command, "-DMIPS=../../../../../../ghidra/Ghidra/Processors/MIPS",
|
||||
"-D8051=../../../../../../ghidra/Ghidra/Processors/8051",
|
||||
inputFile.getAbsolutePath(), targetFile.getAbsolutePath());
|
||||
processBuilder.directory(inputFile.getParentFile().getFile(false));
|
||||
Process process = processBuilder.start();
|
||||
|
||||
new IOThread(process.getInputStream()).start();
|
||||
new IOThread(process.getErrorStream()).start();
|
||||
|
||||
int retval = process.waitFor();
|
||||
return retval;
|
||||
}
|
||||
|
||||
private String getCppSleighCompilerForArch() throws FileNotFoundException {
|
||||
String exeName;
|
||||
if (Platform.CURRENT_PLATFORM.getOperatingSystem() == OperatingSystem.WINDOWS) {
|
||||
exeName = "sleigh.exe";
|
||||
}
|
||||
else {
|
||||
exeName = "sleigh";
|
||||
}
|
||||
File file = Application.getOSFile(exeName);
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
|
||||
private class IOThread extends Thread {
|
||||
private BufferedReader shellOutput;
|
||||
|
||||
public IOThread(InputStream input) {
|
||||
shellOutput = new BufferedReader(new InputStreamReader(input));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String line = null;
|
||||
try {
|
||||
while ((line = shellOutput.readLine()) != null) {
|
||||
System.out.println(line);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
// DO NOT USE LOGGING HERE (class loader)
|
||||
System.err.println("Unexpected Exception: " + e.getMessage());
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int runActualCompiler(File inputFile, File actualFile)
|
||||
throws JDOMException, IOException, RecognitionException {
|
||||
return SleighCompileLauncher.runMain(
|
||||
new String[] { "-DMIPS=../../../../../../ghidra/Ghidra/Processors/MIPS",
|
||||
"-D8051=../../../../../../ghidra/Ghidra/Processors/8051",
|
||||
inputFile.getAbsolutePath(), actualFile.getAbsolutePath() },
|
||||
new HashMap<String, String>());
|
||||
}
|
||||
|
||||
private static final Pattern SPACEMATCH = Pattern.compile("^\\s*<print piece=\" \"/>\\s*$");
|
||||
private static final Pattern TPLMATCH = Pattern.compile("^\\s*<construct_tpl>\\s*$");
|
||||
|
||||
private boolean comparesOK(File actualFile, File targetFile) throws Exception {
|
||||
boolean ok = true;
|
||||
PushbackEntireLine actualReader =
|
||||
new PushbackEntireLine(new BufferedReader(new FileReader(actualFile)));
|
||||
PushbackEntireLine targetReader =
|
||||
new PushbackEntireLine(new BufferedReader(new FileReader(targetFile)));
|
||||
int actualLineNumber = 1;
|
||||
int targetLineNumber = 1;
|
||||
while (true) {
|
||||
try {
|
||||
if (currentLangBadCount >= 100) {
|
||||
ok = itsOK("WAY TOO MANY DIFFERENCES, BAILING", false);
|
||||
break;
|
||||
}
|
||||
String actual = actualReader.readLine();
|
||||
String target = targetReader.readLine();
|
||||
if (target == null) {
|
||||
ok &= itsOK("actual has too many lines", actual == null);
|
||||
break;
|
||||
}
|
||||
if (actual == null) {
|
||||
ok &= itsOK("actual has too few lines", false);
|
||||
break;
|
||||
}
|
||||
|
||||
boolean actualIsSpace = SPACEMATCH.matcher(actual).find();
|
||||
boolean targetIsSpace = SPACEMATCH.matcher(target).find();
|
||||
|
||||
boolean bothSpace = actualIsSpace && targetIsSpace;
|
||||
boolean oneIsSpace = actualIsSpace || targetIsSpace;
|
||||
|
||||
if (!oneIsSpace) {
|
||||
ok &= itsOK(
|
||||
"difference on actual line " + actualLineNumber + ", target line " +
|
||||
targetLineNumber + ":\nEXPECTED:\n" + target + "\nACTUAL:\n" + actual,
|
||||
target.equals(actual));
|
||||
continue;
|
||||
}
|
||||
else if (!bothSpace) {
|
||||
// expected absent trailing space in Java version
|
||||
if (!TPLMATCH.matcher(actual).find()) {
|
||||
ok &= itsOK("difference (space!) on actual line " + actualLineNumber +
|
||||
", target line " + targetLineNumber + ":\nEXPECTED:\n" + target +
|
||||
"\nACTUAL:\n" + actual, false);
|
||||
}
|
||||
}
|
||||
|
||||
while (actualIsSpace) {
|
||||
actual = actualReader.readLine();
|
||||
++actualLineNumber;
|
||||
actualIsSpace = actual != null && SPACEMATCH.matcher(actual).find();
|
||||
}
|
||||
actualReader.putbackLine(actual);
|
||||
--actualLineNumber;
|
||||
|
||||
while (targetIsSpace) {
|
||||
target = targetReader.readLine();
|
||||
++targetLineNumber;
|
||||
targetIsSpace = target != null && SPACEMATCH.matcher(target).find();
|
||||
}
|
||||
targetReader.putbackLine(target);
|
||||
--targetLineNumber;
|
||||
|
||||
}
|
||||
finally {
|
||||
++actualLineNumber;
|
||||
++targetLineNumber;
|
||||
}
|
||||
}
|
||||
actualReader.close();
|
||||
targetReader.close();
|
||||
return ok;
|
||||
}
|
||||
|
||||
private List<ResourceFile> getSlaspecFiles() {
|
||||
List<ResourceFile> allSlaspecFiles =
|
||||
Application.findFilesByExtensionInApplication(".slaspec");
|
||||
return allSlaspecFiles;
|
||||
|
||||
// Predicate<ResourceFile> predicate = new Predicate<ResourceFile>() {
|
||||
// @Override
|
||||
// public boolean accept(ResourceFile t) {
|
||||
// String absolutePath = t.getAbsolutePath();
|
||||
// if (absolutePath.contains("<processor you do not want to include>")) {
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// return Fx.filter(predicate, allSlaspecFiles);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/* ###
|
||||
* 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.program.model.data;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.program.database.data.DataTypeUtilities;
|
||||
|
||||
public class DataTypeUtilitiesTest extends AbstractGenericTest {
|
||||
|
||||
public DataTypeUtilitiesTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetContainedDataTypes() {
|
||||
DataType byteDt = new ByteDataType();
|
||||
DataType wordDt = new WordDataType();
|
||||
Structure simpleStruct = new StructureDataType("simpleStruct", 2);
|
||||
simpleStruct.add(wordDt);
|
||||
simpleStruct.add(byteDt);
|
||||
|
||||
Structure notAsSimpleStruct = new StructureDataType("notAsSimpleStruct", 2);
|
||||
notAsSimpleStruct.add(simpleStruct);
|
||||
notAsSimpleStruct.add(byteDt);
|
||||
|
||||
Structure selfRefStruct = new StructureDataType("selfRefStruct", 2);
|
||||
selfRefStruct.add(byteDt);
|
||||
selfRefStruct.add(new Pointer32DataType(selfRefStruct));
|
||||
|
||||
TypeDef typedef = new TypedefDataType("simpleTypedef", simpleStruct);
|
||||
|
||||
Structure complexStruct = new StructureDataType("complexStruct", 2);
|
||||
complexStruct.add(new Pointer32DataType(typedef));
|
||||
complexStruct.add(notAsSimpleStruct);
|
||||
complexStruct.add(selfRefStruct);
|
||||
|
||||
TypeDef rootDt = new TypedefDataType("root", complexStruct);
|
||||
|
||||
Collection<DataType> dts = DataTypeUtilities.getContainedDataTypes(rootDt);
|
||||
assertEquals(11, dts.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCPrimitiveType() {
|
||||
assertEquals(IntegerDataType.dataType, getType("signed int"));
|
||||
assertEquals(IntegerDataType.dataType, getType(" signed int "));
|
||||
assertEquals(IntegerDataType.dataType, getType("SIGNED int"));
|
||||
assertEquals(UnsignedLongLongDataType.dataType, getType("unsigned long long int"));
|
||||
assertNull(getType("foo bar"));
|
||||
}
|
||||
|
||||
private DataType getType(String typeName) {
|
||||
return DataTypeUtilities.getCPrimitiveDataType(typeName);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,496 @@
|
|||
/* ###
|
||||
* 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.program.model.data;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
|
||||
public class DataTypeWriterTest extends AbstractGenericTest {
|
||||
|
||||
private static String EOL = System.getProperty("line.separator");
|
||||
|
||||
private StringWriter writer;
|
||||
private DataTypeWriter dtWriter;
|
||||
|
||||
public DataTypeWriterTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
writer = new StringWriter();
|
||||
dtWriter = new DataTypeWriter(null, writer); // uses default data organization
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
|
||||
writer.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeDef() throws IOException, CancelledException {
|
||||
TypeDef typedef = new TypedefDataType("BOB", new CharDataType());
|
||||
dtWriter.write(typedef, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
String actual = writer.getBuffer().toString();
|
||||
String expected = "typedef char BOB;" + EOL + EOL;
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeDef2() throws IOException, CancelledException {
|
||||
TypeDef typedef = new TypedefDataType("unsigned int", new DWordDataType());
|
||||
dtWriter.write(typedef, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
String actual = writer.getBuffer().toString();
|
||||
String expected = "";
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeDef3() throws IOException, CancelledException {
|
||||
TypeDef typedef = new TypedefDataType("const float", new DWordDataType());
|
||||
dtWriter.write(typedef, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
String actual = writer.getBuffer().toString();
|
||||
String expected = "";
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeDef4() throws IOException, CancelledException {
|
||||
Structure struct = new StructureDataType("MyBasicStruct", 0);
|
||||
struct.add(new CharDataType());
|
||||
struct.add(new ByteDataType());
|
||||
|
||||
Pointer pointer1 = PointerDataType.getPointer(struct, 4);
|
||||
|
||||
Pointer pointer2 = PointerDataType.getPointer(pointer1, 4);
|
||||
|
||||
TypeDef typedef =
|
||||
new TypedefDataType("static const " + pointer2.getDisplayName(), pointer2);
|
||||
dtWriter.write(typedef, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
String actual = writer.getBuffer().toString();
|
||||
String expected = "";
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnum() throws IOException, CancelledException {
|
||||
Enum enumm = new EnumDataType("myEnum", 1);
|
||||
enumm.add("A", 0);
|
||||
enumm.add("B", 1);
|
||||
enumm.add("C", 2);
|
||||
enumm.add("D", 3);
|
||||
enumm.add("E", 4);
|
||||
dtWriter.write(enumm, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
String actual = writer.getBuffer().toString();
|
||||
String expected = "typedef enum myEnum {" + EOL + " A=0," + EOL + " B=1," + EOL +
|
||||
" C=2," + EOL + " D=3," + EOL + " E=4" + EOL + "} myEnum;" + EOL + EOL;
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnum2() throws IOException, CancelledException {
|
||||
Enum enumm = new EnumDataType("myEnum", 1);
|
||||
enumm.add("A", 4);
|
||||
enumm.add("B", 8);
|
||||
enumm.add("C", 16);
|
||||
enumm.add("D", 32);
|
||||
enumm.add("E", 254);
|
||||
dtWriter.write(enumm, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
String actual = writer.getBuffer().toString();
|
||||
String expected = "typedef enum myEnum {" + EOL + " A=4," + EOL + " B=8," + EOL +
|
||||
" C=16," + EOL + " D=32," + EOL + " E=254" + EOL + "} myEnum;" + EOL + EOL;
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStructure() throws IOException, CancelledException {
|
||||
Structure struct = new StructureDataType("MyStruct", 0);
|
||||
struct.setDescription("this is my structure");
|
||||
struct.add(new CharDataType(), "myChar", "this is a character");
|
||||
struct.add(new ByteDataType(), "myByte", "this is a byte");
|
||||
struct.add(new WordDataType(), "myWord", "this is a word");
|
||||
struct.add(new DWordDataType(), "myDWord", "this is a dword");
|
||||
struct.add(new QWordDataType(), "myQWord", "this is a qword");
|
||||
struct.add(new FloatDataType(), "myFloat", "this is a float");
|
||||
struct.add(new DoubleDataType(), "myDouble", "this is a double");
|
||||
struct.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
|
||||
"this is a float pointer");
|
||||
struct.setFlexibleArrayComponent(new CharDataType(), "myFlexArray", "this is a flex array");
|
||||
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
String actual = writer.getBuffer().toString();
|
||||
String expected = "typedef struct MyStruct MyStruct, *PMyStruct;" + EOL + EOL +
|
||||
"typedef unsigned char byte;" + EOL + "typedef unsigned short word;" + EOL +
|
||||
"typedef unsigned int dword;" + EOL + "typedef unsigned long long qword;" + EOL +
|
||||
"struct MyStruct { /* this is my structure */" + EOL +
|
||||
" char myChar; /* this is a character */" + EOL +
|
||||
" byte myByte; /* this is a byte */" + EOL +
|
||||
" word myWord; /* this is a word */" + EOL +
|
||||
" dword myDWord; /* this is a dword */" + EOL +
|
||||
" qword myQWord; /* this is a qword */" + EOL +
|
||||
" float myFloat; /* this is a float */" + EOL +
|
||||
" double myDouble; /* this is a double */" + EOL +
|
||||
" float * myFloatPointer; /* this is a float pointer */" + EOL +
|
||||
" char[0] myFlexArray; /* this is a flex array */" + EOL + "};" + EOL + EOL;
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStructureBasic() throws IOException, CancelledException {
|
||||
Structure struct = new StructureDataType("MyBasicStruct", 0);
|
||||
struct.add(new CharDataType());
|
||||
struct.add(new ByteDataType());
|
||||
struct.add(new WordDataType());
|
||||
struct.add(new DWordDataType());
|
||||
struct.add(new QWordDataType());
|
||||
struct.add(new FloatDataType());
|
||||
struct.add(new DoubleDataType());
|
||||
struct.add(PointerDataType.getPointer(new FloatDataType(), 4));
|
||||
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
String actual = writer.getBuffer().toString();
|
||||
String expected = "typedef struct MyBasicStruct MyBasicStruct, *PMyBasicStruct;" + EOL +
|
||||
EOL + "typedef unsigned char byte;" + EOL + "typedef unsigned short word;" + EOL +
|
||||
"typedef unsigned int dword;" + EOL + "typedef unsigned long long qword;" + EOL +
|
||||
"struct MyBasicStruct {" + EOL + " char field_0x0;" + EOL + " byte field_0x1;" +
|
||||
EOL + " word field_0x2;" + EOL + " dword field_0x4;" + EOL +
|
||||
" qword field_0x8;" + EOL + " float field_0x10;" + EOL +
|
||||
" double field_0x14;" + EOL + " float * field_0x1c;" + EOL + "};" + EOL + EOL;
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStructureInStructure() throws IOException, CancelledException {
|
||||
Structure innerStructure = new StructureDataType("MyInnerStructure", 0);
|
||||
innerStructure.setDescription("this is my inner structure");
|
||||
innerStructure.add(new CharDataType(), "myInnerChar", "this is a inner character");
|
||||
innerStructure.add(new ByteDataType(), "myInnerByte", "this is a inner byte");
|
||||
|
||||
Structure outerStructure = new StructureDataType("MyOuterStructure", 0);
|
||||
outerStructure.setDescription("this is my outer structure");
|
||||
outerStructure.add(new FloatDataType(), "myOuterFloat", "this is a outer float");
|
||||
outerStructure.add(new TypedefDataType("int", new DWordDataType()), "myOuterInt",
|
||||
"this is a outer int");
|
||||
outerStructure.add(innerStructure, "myOuterInnerStructure",
|
||||
"this is a outer inner structure");
|
||||
outerStructure.add(new CharDataType(), "myOuterChar", "this is a outer character");
|
||||
|
||||
dtWriter.write(outerStructure, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
|
||||
String actual = writer.getBuffer().toString();
|
||||
|
||||
String expected = "typedef struct MyOuterStructure MyOuterStructure, *PMyOuterStructure;" +
|
||||
EOL + EOL + "typedef struct MyInnerStructure MyInnerStructure, *PMyInnerStructure;" +
|
||||
EOL + EOL + "typedef unsigned char byte;" + EOL +
|
||||
"struct MyInnerStructure { /* this is my inner structure */" + EOL +
|
||||
" char myInnerChar; /* this is a inner character */" + EOL +
|
||||
" byte myInnerByte; /* this is a inner byte */" + EOL + "};" + EOL + EOL +
|
||||
"struct MyOuterStructure { /* this is my outer structure */" + EOL +
|
||||
" float myOuterFloat; /* this is a outer float */" + EOL +
|
||||
" int myOuterInt; /* this is a outer int */" + EOL +
|
||||
" struct MyInnerStructure myOuterInnerStructure; /* this is a outer inner structure */" +
|
||||
EOL + " char myOuterChar; /* this is a outer character */" + EOL + "};" + EOL + EOL;
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStructureInUnion() throws IOException, CancelledException {
|
||||
Structure innerStructure = new StructureDataType("MyInnerStructure", 0);
|
||||
innerStructure.setDescription("this is my inner structure");
|
||||
innerStructure.add(new CharDataType(), "myInnerChar", "this is a inner character");
|
||||
innerStructure.add(new ByteDataType(), "myInnerByte", "this is a inner byte");
|
||||
|
||||
Union outerUnion = new UnionDataType("MyOuterUnion");
|
||||
outerUnion.setDescription("this is my outer union");
|
||||
outerUnion.add(new FloatDataType(), "myOuterFloat", "this is a outer float");
|
||||
outerUnion.add(new TypedefDataType("int", new DWordDataType()), "myOuterInt",
|
||||
"this is a outer int");
|
||||
outerUnion.add(innerStructure, "myOuterInnerStructure", "this is a outer inner structure");
|
||||
outerUnion.add(new CharDataType(), "myOuterChar", "this is a outer character");
|
||||
|
||||
dtWriter.write(outerUnion, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
|
||||
String actual = writer.getBuffer().toString();
|
||||
|
||||
String expected = "typedef union MyOuterUnion MyOuterUnion, *PMyOuterUnion;" + EOL + EOL +
|
||||
"typedef struct MyInnerStructure MyInnerStructure, *PMyInnerStructure;" + EOL + EOL +
|
||||
"typedef unsigned char byte;" + EOL +
|
||||
"struct MyInnerStructure { /* this is my inner structure */" + EOL +
|
||||
" char myInnerChar; /* this is a inner character */" + EOL +
|
||||
" byte myInnerByte; /* this is a inner byte */" + EOL + "};" + EOL + EOL +
|
||||
"union MyOuterUnion { /* this is my outer union */" + EOL +
|
||||
" float myOuterFloat; /* this is a outer float */" + EOL +
|
||||
" int myOuterInt; /* this is a outer int */" + EOL +
|
||||
" struct MyInnerStructure myOuterInnerStructure; /* this is a outer inner structure */" +
|
||||
EOL + " char myOuterChar; /* this is a outer character */" + EOL + "};" + EOL + EOL;
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStructureSelfReference() throws IOException, CancelledException {
|
||||
Structure struct = new StructureDataType("MySelfRefStruct", 0);
|
||||
struct.add(new WordDataType());
|
||||
struct.add(PointerDataType.getPointer(struct, 4));
|
||||
struct.add(new DoubleDataType());
|
||||
|
||||
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
String actual = writer.getBuffer().toString();
|
||||
String expected = "typedef struct MySelfRefStruct MySelfRefStruct, *PMySelfRefStruct;" +
|
||||
EOL + EOL + "typedef unsigned short word;" + EOL + "struct MySelfRefStruct {" + EOL +
|
||||
" word field_0x0;" + EOL + " struct MySelfRefStruct * field_0x2;" + EOL +
|
||||
" double field_0x6;" + EOL + "};" + EOL + EOL;
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnion() throws IOException, CancelledException {
|
||||
Union union = new UnionDataType("MyUnion");
|
||||
union.setDescription("this is my union");
|
||||
union.add(new CharDataType(), "myChar", "this is a character");
|
||||
union.add(new ByteDataType(), "myByte", "this is a byte");
|
||||
union.add(new WordDataType(), "myWord", "this is a word");
|
||||
union.add(new DWordDataType(), "myDWord", "this is a dword");
|
||||
union.add(new QWordDataType(), "myQWord", "this is a qword");
|
||||
union.add(new FloatDataType(), "myFloat", "this is a float");
|
||||
union.add(new DoubleDataType(), "myDouble", "this is a double");
|
||||
union.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
|
||||
"this is a float pointer");
|
||||
dtWriter.write(union, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
String actual = writer.getBuffer().toString();
|
||||
String expected = "typedef union MyUnion MyUnion, *PMyUnion;" + EOL + EOL +
|
||||
"typedef unsigned char byte;" + EOL + "typedef unsigned short word;" + EOL +
|
||||
"typedef unsigned int dword;" + EOL + "typedef unsigned long long qword;" + EOL +
|
||||
"union MyUnion { /* this is my union */" + EOL +
|
||||
" char myChar; /* this is a character */" + EOL +
|
||||
" byte myByte; /* this is a byte */" + EOL +
|
||||
" word myWord; /* this is a word */" + EOL +
|
||||
" dword myDWord; /* this is a dword */" + EOL +
|
||||
" qword myQWord; /* this is a qword */" + EOL +
|
||||
" float myFloat; /* this is a float */" + EOL +
|
||||
" double myDouble; /* this is a double */" + EOL +
|
||||
" float * myFloatPointer; /* this is a float pointer */" + EOL + "};" + EOL + EOL;
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnionInUnion() throws IOException, CancelledException {
|
||||
Union innerUnion = new UnionDataType("MyInnerUnion");
|
||||
innerUnion.setDescription("this is my inner union");
|
||||
innerUnion.add(new CharDataType(), "myInnerChar", "this is a inner character");
|
||||
innerUnion.add(new ByteDataType(), "myInnerByte", "this is a inner byte");
|
||||
|
||||
Union outerUnion = new UnionDataType("MyOuterUnion");
|
||||
outerUnion.setDescription("this is my outer union");
|
||||
outerUnion.add(new FloatDataType(), "myOuterFloat", "this is a outer float");
|
||||
outerUnion.add(new TypedefDataType("int", new DWordDataType()), "myOuterInt",
|
||||
"this is a outer int");
|
||||
outerUnion.add(innerUnion, "myOuterInnerUnion", "this is a outer inner union");
|
||||
outerUnion.add(new CharDataType(), "myOuterChar", "this is a outer character");
|
||||
|
||||
dtWriter.write(outerUnion, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
|
||||
String actual = writer.getBuffer().toString();
|
||||
|
||||
String expected = "typedef union MyOuterUnion MyOuterUnion, *PMyOuterUnion;" + EOL + EOL +
|
||||
"typedef union MyInnerUnion MyInnerUnion, *PMyInnerUnion;" + EOL + EOL +
|
||||
"typedef unsigned char byte;" + EOL +
|
||||
"union MyInnerUnion { /* this is my inner union */" + EOL +
|
||||
" char myInnerChar; /* this is a inner character */" + EOL +
|
||||
" byte myInnerByte; /* this is a inner byte */" + EOL + "};" + EOL + EOL +
|
||||
"union MyOuterUnion { /* this is my outer union */" + EOL +
|
||||
" float myOuterFloat; /* this is a outer float */" + EOL +
|
||||
" int myOuterInt; /* this is a outer int */" + EOL +
|
||||
" union MyInnerUnion myOuterInnerUnion; /* this is a outer inner union */" + EOL +
|
||||
" char myOuterChar; /* this is a outer character */" + EOL + "};" + EOL + EOL;
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnionInStructure() throws IOException, CancelledException {
|
||||
Union innerUnion = new UnionDataType("MyInnerUnion");
|
||||
innerUnion.setDescription("this is my inner union");
|
||||
innerUnion.add(new CharDataType(), "myInnerChar", "this is a inner character");
|
||||
innerUnion.add(new ByteDataType(), "myInnerByte", "this is a inner byte");
|
||||
|
||||
Structure outerStructure = new StructureDataType("MyOuterStructure", 0);
|
||||
outerStructure.setDescription("this is my outer structure");
|
||||
outerStructure.add(new FloatDataType(), "myOuterFloat", "this is a outer float");
|
||||
outerStructure.add(new TypedefDataType("int", new DWordDataType()), "myOuterInt",
|
||||
"this is a outer int");
|
||||
outerStructure.add(innerUnion, "myOuterInnerUnion", "this is a outer inner union");
|
||||
outerStructure.add(new CharDataType(), "myOuterChar", "this is a outer character");
|
||||
|
||||
dtWriter.write(outerStructure, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
|
||||
String actual = writer.getBuffer().toString();
|
||||
|
||||
String expected = "typedef struct MyOuterStructure MyOuterStructure, *PMyOuterStructure;" +
|
||||
EOL + EOL + "typedef union MyInnerUnion MyInnerUnion, *PMyInnerUnion;" + EOL + EOL +
|
||||
"typedef unsigned char byte;" + EOL +
|
||||
"union MyInnerUnion { /* this is my inner union */" + EOL +
|
||||
" char myInnerChar; /* this is a inner character */" + EOL +
|
||||
" byte myInnerByte; /* this is a inner byte */" + EOL + "};" + EOL + EOL +
|
||||
"struct MyOuterStructure { /* this is my outer structure */" + EOL +
|
||||
" float myOuterFloat; /* this is a outer float */" + EOL +
|
||||
" int myOuterInt; /* this is a outer int */" + EOL +
|
||||
" union MyInnerUnion myOuterInnerUnion; /* this is a outer inner union */" + EOL +
|
||||
" char myOuterChar; /* this is a outer character */" + EOL + "};" + EOL + EOL;
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArray() {
|
||||
//TODO
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSizableDynamicInStructure() throws IOException, CancelledException {
|
||||
Structure struct = new StructureDataType("MyStruct", 0);
|
||||
struct.setDescription("this is my structure");
|
||||
struct.add(new QWordDataType(), "myQWord", "this is my qword");
|
||||
struct.add(new StringDataType(), 10, "myStr", "this is my string");
|
||||
struct.add(new DoubleDataType(), "myDouble", "this is my double");
|
||||
struct.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
|
||||
"this is my float pointer");
|
||||
|
||||
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
|
||||
String actual = writer.getBuffer().toString();
|
||||
|
||||
String expected = "typedef struct MyStruct MyStruct, *PMyStruct;" + EOL + EOL +
|
||||
"typedef unsigned long long qword;" + EOL +
|
||||
"struct MyStruct { /* this is my structure */" + EOL +
|
||||
" qword myQWord; /* this is my qword */" + EOL +
|
||||
" char myStr[10]; /* this is my string */" + EOL +
|
||||
" double myDouble; /* this is my double */" + EOL +
|
||||
" float * myFloatPointer; /* this is my float pointer */" + EOL + "};" + EOL + EOL;
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrayInStructure() throws IOException, CancelledException {
|
||||
DataType dt = new FloatDataType();
|
||||
Array array = new ArrayDataType(dt, 300, dt.getLength());
|
||||
|
||||
Structure struct = new StructureDataType("MyStruct", 0);
|
||||
struct.setDescription("this is my structure");
|
||||
struct.add(new QWordDataType(), "myQWord", "this is my qword");
|
||||
struct.add(array, "myArray", "this is my array");
|
||||
struct.add(new DoubleDataType(), "myDouble", "this is my double");
|
||||
struct.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
|
||||
"this is my float pointer");
|
||||
|
||||
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
|
||||
String actual = writer.getBuffer().toString();
|
||||
|
||||
String expected = "typedef struct MyStruct MyStruct, *PMyStruct;" + EOL + EOL +
|
||||
"typedef unsigned long long qword;" + EOL +
|
||||
"struct MyStruct { /* this is my structure */" + EOL +
|
||||
" qword myQWord; /* this is my qword */" + EOL +
|
||||
" float myArray[300]; /* this is my array */" + EOL +
|
||||
" double myDouble; /* this is my double */" + EOL +
|
||||
" float * myFloatPointer; /* this is my float pointer */" + EOL + "};" + EOL + EOL;
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrayInUnion() throws IOException, CancelledException {
|
||||
DataType dt = new FloatDataType();
|
||||
Array array = new ArrayDataType(dt, 300, dt.getLength());
|
||||
|
||||
Union union = new UnionDataType("MyUnion");
|
||||
union.setDescription("this is my union");
|
||||
union.add(new QWordDataType(), "myQWord", "this is my qword");
|
||||
union.add(array, "myArray", "this is my array");
|
||||
union.add(new DoubleDataType(), "myDouble", "this is my double");
|
||||
union.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
|
||||
"this is my float pointer");
|
||||
|
||||
dtWriter.write(union, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
|
||||
String actual = writer.getBuffer().toString();
|
||||
|
||||
String expected = "typedef union MyUnion MyUnion, *PMyUnion;" + EOL + EOL +
|
||||
"typedef unsigned long long qword;" + EOL +
|
||||
"union MyUnion { /* this is my union */" + EOL +
|
||||
" qword myQWord; /* this is my qword */" + EOL +
|
||||
" float myArray[300]; /* this is my array */" + EOL +
|
||||
" double myDouble; /* this is my double */" + EOL +
|
||||
" float * myFloatPointer; /* this is my float pointer */" + EOL + "};" + EOL + EOL;
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnionSelfReference() throws IOException, CancelledException {
|
||||
Union union = new UnionDataType("MySelfRefUnion");
|
||||
union.add(new WordDataType());
|
||||
union.add(PointerDataType.getPointer(union, 4));
|
||||
union.add(new DoubleDataType());
|
||||
|
||||
dtWriter.write(union, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
String actual = writer.getBuffer().toString();
|
||||
String expected = "typedef union MySelfRefUnion MySelfRefUnion, *PMySelfRefUnion;" + EOL +
|
||||
EOL + "typedef unsigned short word;" + EOL + "union MySelfRefUnion {" + EOL +
|
||||
" word field0;" + EOL + " union MySelfRefUnion * field1;" + EOL +
|
||||
" double field2;" + EOL + "};" + EOL + EOL;
|
||||
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPointer() throws IOException, CancelledException {
|
||||
|
||||
// Only base type is written-out - not pointer
|
||||
|
||||
Pointer ptr = PointerDataType.getPointer(null, null);
|
||||
dtWriter.write(ptr, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
String actual = writer.getBuffer().toString();
|
||||
String expected = "";
|
||||
assertEquals(expected, actual);
|
||||
|
||||
ptr = PointerDataType.getPointer(DataType.DEFAULT, null);
|
||||
dtWriter.write(ptr, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
actual = writer.getBuffer().toString();
|
||||
expected += "typedef unsigned char undefined;" + EOL + EOL;
|
||||
assertEquals(expected, actual);
|
||||
|
||||
TypeDef typedef = new TypedefDataType("BOB", new CharDataType());
|
||||
ptr = PointerDataType.getPointer(typedef, null);
|
||||
dtWriter.write(ptr, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
actual = writer.getBuffer().toString();
|
||||
expected += "typedef char BOB;" + EOL + EOL;
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,271 @@
|
|||
/* ###
|
||||
* 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.program.model.data;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
|
||||
/**
|
||||
* Tests for Enum data types.
|
||||
*/
|
||||
public class EnumTest extends AbstractGenericTest {
|
||||
|
||||
private DataTypeManager dataMgr;
|
||||
private int transactionID;
|
||||
|
||||
/**
|
||||
* Constructor for EnumTest.
|
||||
* @param arg0
|
||||
*/
|
||||
public EnumTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see TestCase#setUp()
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
dataMgr = new StandAloneDataTypeManager("Test");
|
||||
transactionID = dataMgr.startTransaction("");
|
||||
}
|
||||
@After
|
||||
public void tearDown() {
|
||||
dataMgr.endTransaction(transactionID, true);
|
||||
dataMgr.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateEnum() throws Exception {
|
||||
Enum enumm = new EnumDataType("Color", 1);
|
||||
enumm.add("Red", 0);
|
||||
enumm.add("Green", 1);
|
||||
enumm.add("Blue", 2);
|
||||
|
||||
Category root = dataMgr.getRootCategory();
|
||||
Category c = root.createCategory("enumms");
|
||||
|
||||
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
|
||||
assertNotNull(enummDT);
|
||||
|
||||
assertEquals("Color", enummDT.getName());
|
||||
assertEquals(0, enummDT.getValue("Red"));
|
||||
assertEquals(1, enummDT.getValue("Green"));
|
||||
assertEquals(2, enummDT.getValue("Blue"));
|
||||
|
||||
assertEquals(1, enummDT.getLength());
|
||||
assertEquals(3, enummDT.getCount());
|
||||
|
||||
assertTrue(enumm.isEquivalent(enummDT));
|
||||
assertTrue(enummDT.isEquivalent(enumm));
|
||||
|
||||
assertEquals(c.getCategoryPath(), enummDT.getCategoryPath());
|
||||
|
||||
assertNotNull(c.getDataType("Color"));
|
||||
}
|
||||
@Test
|
||||
public void testRemoveValue() throws Exception {
|
||||
Enum enumm = new EnumDataType("Color", 1);
|
||||
enumm.add("Red", 0);
|
||||
enumm.add("Green", 1);
|
||||
enumm.add("Blue", 2);
|
||||
|
||||
Category root = dataMgr.getRootCategory();
|
||||
Category c = root.createCategory("enumms");
|
||||
|
||||
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
assertEquals(3, enummDT.getCount());
|
||||
enummDT.remove("Green");
|
||||
assertEquals(2, enummDT.getCount());
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testAddValue() throws Exception {
|
||||
Enum enumm = new EnumDataType("Color", 1);
|
||||
enumm.add("Red", 0);
|
||||
enumm.add("Green", 1);
|
||||
enumm.add("Blue", 2);
|
||||
|
||||
Category root = dataMgr.getRootCategory();
|
||||
Category c = root.createCategory("enumms");
|
||||
|
||||
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
|
||||
enummDT.add("Purple", 7);
|
||||
assertEquals(4, enummDT.getCount());
|
||||
assertEquals(7, enummDT.getValue("Purple"));
|
||||
}
|
||||
@Test
|
||||
public void testEditValue() throws Exception {
|
||||
Enum enumm = new EnumDataType("Color", 1);
|
||||
enumm.add("Red", 10);
|
||||
enumm.add("Green", 15);
|
||||
enumm.add("Blue", 20);
|
||||
Category root = dataMgr.getRootCategory();
|
||||
Category c = root.createCategory("enumms");
|
||||
|
||||
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
enummDT.remove("Blue");
|
||||
assertEquals(2, enummDT.getCount());
|
||||
enummDT.add("Blue", 30);
|
||||
assertEquals(30, enummDT.getValue("Blue"));
|
||||
assertEquals("Blue", enummDT.getName(30));
|
||||
assertNull(enummDT.getName(20));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloneRetain() throws Exception {
|
||||
Enum enumm = new EnumDataType("Color", 1);
|
||||
enumm.add("Red", 10);
|
||||
enumm.add("Green", 15);
|
||||
enumm.add("Blue", 20);
|
||||
Category root = dataMgr.getRootCategory();
|
||||
Category c = root.createCategory("enumms");
|
||||
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
|
||||
Enum copyDT = (Enum)enummDT.clone(null);
|
||||
assertNotNull(copyDT);
|
||||
|
||||
Enum c2 = (Enum)root.addDataType(copyDT, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
assertNotNull(c2);
|
||||
assertTrue(copyDT.isEquivalent(c2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyDontRetain() throws Exception {
|
||||
Enum enumm = new EnumDataType("Color", 1);
|
||||
enumm.add("Red", 10);
|
||||
enumm.add("Green", 15);
|
||||
enumm.add("Blue", 20);
|
||||
Category root = dataMgr.getRootCategory();
|
||||
Category c = root.createCategory("enumms");
|
||||
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
|
||||
Enum copyDT = (Enum)enummDT.copy(null);
|
||||
assertNotNull(copyDT);
|
||||
|
||||
Enum c2 = (Enum)root.addDataType(copyDT, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
assertNotNull(c2);
|
||||
assertTrue(copyDT.isEquivalent(c2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveEnum() throws Exception {
|
||||
Enum enumm = new EnumDataType("Color", 1);
|
||||
enumm.add("Red", 10);
|
||||
enumm.add("Green", 15);
|
||||
enumm.add("Blue", 20);
|
||||
Category root = dataMgr.getRootCategory();
|
||||
Category c = root.createCategory("enumms");
|
||||
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
assertNotNull(enummDT);
|
||||
|
||||
c.remove(enummDT, TaskMonitorAdapter.DUMMY_MONITOR);
|
||||
assertNull(c.getDataType("Color"));
|
||||
|
||||
assertTrue(enummDT.isDeleted());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveEnum() throws Exception {
|
||||
Enum enumm = new EnumDataType("Color", 1);
|
||||
enumm.add("Red", 10);
|
||||
enumm.add("Green", 15);
|
||||
enumm.add("Blue", 20);
|
||||
Category root = dataMgr.getRootCategory();
|
||||
Category c = root.createCategory("enumms");
|
||||
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
|
||||
root.moveDataType(enummDT, null);
|
||||
assertNotNull(root.getDataType(enumm.getName()));
|
||||
assertNull(c.getDataType(enumm.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolve() throws Exception {
|
||||
Enum enumm = new EnumDataType("Color", 1);
|
||||
enumm.add("Red", 10);
|
||||
enumm.add("Green", 15);
|
||||
enumm.add("Blue", 20);
|
||||
|
||||
Enum enummDT = (Enum)dataMgr.resolve(enumm, null);
|
||||
assertNotNull(enummDT);
|
||||
|
||||
long id = dataMgr.getResolvedID(enummDT);
|
||||
|
||||
assertEquals(enummDT, dataMgr.getDataType(id));
|
||||
}
|
||||
@Test
|
||||
public void testReplace() throws Exception {
|
||||
Enum enumm = new EnumDataType("Color", 1);
|
||||
enumm.add("Red", 10);
|
||||
enumm.add("Green", 15);
|
||||
enumm.add("Blue", 20);
|
||||
Category root = dataMgr.getRootCategory();
|
||||
Category c = root.createCategory("enumms");
|
||||
Enum enummDT = (Enum)c.addDataType(enumm, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
|
||||
Enum myEnum = new EnumDataType("my enumm", 1);
|
||||
myEnum.add("My red", 0);
|
||||
myEnum.add("My Green", 5);
|
||||
myEnum.add("My Blue", 25);
|
||||
myEnum.add("Purple", 10);
|
||||
|
||||
enummDT.replaceWith(myEnum);
|
||||
|
||||
assertEquals(4, enummDT.getCount());
|
||||
long[] values = enummDT.getValues();
|
||||
assertEquals(4, values.length);
|
||||
|
||||
assertEquals(0, values[0]);
|
||||
assertEquals(5, values[1]);
|
||||
assertEquals(10, values[2]);
|
||||
assertEquals(25, values[3]);
|
||||
|
||||
try {
|
||||
enummDT.getValue("Red");
|
||||
Assert.fail("Should have gotten no such element exception!");
|
||||
} catch (NoSuchElementException e) {
|
||||
}
|
||||
}
|
||||
|
||||
// private class DomainObjListener implements DomainObjectListener {
|
||||
// private int count;
|
||||
//
|
||||
// /* (non-Javadoc)
|
||||
// * @see ghidra.framework.model.DomainObjectListener#domainObjectChanged(ghidra.framework.model.DomainObjectChangedEvent)
|
||||
// */
|
||||
// public void domainObjectChanged(DomainObjectChangedEvent ev) {
|
||||
// for (int i=0; i<ev.numRecords(); i++) {
|
||||
// DomainObjectChangeRecord rec = ev.getChangeRecord(i);
|
||||
// if (rec.getEventType() == ChangeManager.DOCR_DATA_TYPE_CHANGED) {
|
||||
// ++count;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// int getCount() {
|
||||
// return count;
|
||||
// }
|
||||
// }
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
/* ###
|
||||
* 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.program.model.data;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
|
||||
public class FileDataTypeManagerTest extends AbstractGenericTest {
|
||||
|
||||
private File testArchiveFile;
|
||||
|
||||
public FileDataTypeManagerTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
testArchiveFile =
|
||||
File.createTempFile("TestArchive", ".gdt", new File(getTestDirectoryPath()));
|
||||
testArchiveFile.delete();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
testArchiveFile.delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateAndOpenArchive() {
|
||||
|
||||
FileDataTypeManager dtMgr = null;
|
||||
|
||||
try {
|
||||
dtMgr = FileDataTypeManager.createFileArchive(testArchiveFile);
|
||||
assertTrue(dtMgr.isUpdatable());
|
||||
DataType dt1, dt2;
|
||||
int txId = dtMgr.startTransaction("Add Types");
|
||||
try {
|
||||
dt1 =
|
||||
dtMgr.addDataType(new TypedefDataType("T1", ByteDataType.dataType), null).clone(
|
||||
null);
|
||||
dt2 =
|
||||
dtMgr.addDataType(new TypedefDataType("T2", ByteDataType.dataType), null).clone(
|
||||
null);
|
||||
}
|
||||
finally {
|
||||
dtMgr.endTransaction(txId, true);
|
||||
}
|
||||
assertTrue(dtMgr.isChanged());
|
||||
dtMgr.save();
|
||||
dtMgr.close();
|
||||
dtMgr = null;
|
||||
|
||||
dtMgr = FileDataTypeManager.openFileArchive(testArchiveFile, false);
|
||||
assertFalse(dtMgr.isUpdatable());
|
||||
|
||||
ArrayList<DataType> list = new ArrayList<DataType>();
|
||||
dtMgr.getAllDataTypes(list);
|
||||
|
||||
int size = list.size();
|
||||
if (size != 3) {
|
||||
|
||||
StringBuilder buffy = new StringBuilder();
|
||||
for (DataType dt : list) {
|
||||
buffy.append(dt.getName()).append(" - ").append(dt.getDescription()).append(
|
||||
"\n");
|
||||
}
|
||||
|
||||
Assert.fail("Did not get exptected data types of byte, Typdef and Typedef. Instead found:\n" +
|
||||
buffy.toString());
|
||||
}
|
||||
|
||||
assertTrue(dt1.isEquivalent(dtMgr.getDataType(CategoryPath.ROOT, "T1")));
|
||||
assertTrue(dt2.isEquivalent(dtMgr.getDataType(CategoryPath.ROOT, "T2")));
|
||||
|
||||
dtMgr.close();
|
||||
dtMgr = null;
|
||||
}
|
||||
catch (IOException e) {
|
||||
Assert.fail("Unexpected Exception");
|
||||
}
|
||||
finally {
|
||||
if (dtMgr != null) {
|
||||
dtMgr.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModifyArchive() {
|
||||
|
||||
testCreateAndOpenArchive(); // establish archive
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
|
||||
FileDataTypeManager dtMgr = null;
|
||||
try {
|
||||
dtMgr = FileDataTypeManager.openFileArchive(testArchiveFile, true);
|
||||
assertTrue("Archive not updateable, i=" + i, dtMgr.isUpdatable());
|
||||
|
||||
int txId = dtMgr.startTransaction("Add Type");
|
||||
try {
|
||||
dtMgr.addDataType(new TypedefDataType("X" + i, ByteDataType.dataType), null);
|
||||
|
||||
}
|
||||
finally {
|
||||
dtMgr.endTransaction(txId, true);
|
||||
}
|
||||
|
||||
dtMgr.save();
|
||||
dtMgr.close();
|
||||
dtMgr = null;
|
||||
}
|
||||
catch (IOException e) {
|
||||
Assert.fail("Unexpected Exception");
|
||||
}
|
||||
finally {
|
||||
if (dtMgr != null) {
|
||||
dtMgr.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
FileDataTypeManager dtMgr = null;
|
||||
|
||||
try {
|
||||
dtMgr = FileDataTypeManager.openFileArchive(testArchiveFile, false);
|
||||
assertFalse(dtMgr.isUpdatable());
|
||||
|
||||
ArrayList<DataType> list = new ArrayList<DataType>();
|
||||
dtMgr.getAllDataTypes(list);
|
||||
assertEquals(13, list.size());
|
||||
|
||||
dtMgr.close();
|
||||
dtMgr = null;
|
||||
}
|
||||
catch (IOException e) {
|
||||
Assert.fail("Unexpected Exception");
|
||||
}
|
||||
finally {
|
||||
if (dtMgr != null) {
|
||||
dtMgr.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
/* ###
|
||||
* 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.program.model.data;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.program.model.mem.ByteMemBufferImpl;
|
||||
|
||||
public class FloatDataTypeTest extends AbstractGenericTest {
|
||||
|
||||
/**
|
||||
* Constructor for LongDoubleDataTypeTest.
|
||||
* @param arg0
|
||||
*/
|
||||
public FloatDataTypeTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
private byte[] getBytes(long value, int size) {
|
||||
byte[] bytes = new byte[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
bytes[i] = (byte) value;
|
||||
value >>= 8;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloat4Extremes() {
|
||||
|
||||
int bits = Float.floatToRawIntBits(Float.NaN);
|
||||
byte[] bytes = getBytes(bits, 4);
|
||||
Object value =
|
||||
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(Float.NaN, value);
|
||||
|
||||
bits = Float.floatToRawIntBits(Float.POSITIVE_INFINITY);
|
||||
bytes = getBytes(bits, 4);
|
||||
value =
|
||||
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(Float.POSITIVE_INFINITY, value);
|
||||
|
||||
bits = Float.floatToRawIntBits(Float.NEGATIVE_INFINITY);
|
||||
bytes = getBytes(bits, 4);
|
||||
value =
|
||||
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(Float.NEGATIVE_INFINITY, value);
|
||||
|
||||
bits = Float.floatToRawIntBits(0F);
|
||||
bytes = getBytes(bits, 4);
|
||||
value =
|
||||
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(0F, value);
|
||||
|
||||
bits = Float.floatToRawIntBits(1F);
|
||||
bytes = getBytes(bits, 4);
|
||||
value =
|
||||
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(1F, value);
|
||||
|
||||
bits = Float.floatToRawIntBits(-1F);
|
||||
bytes = getBytes(bits, 4);
|
||||
value =
|
||||
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(-1F, value);
|
||||
|
||||
bits = Float.floatToRawIntBits(555.555F);
|
||||
bytes = getBytes(bits, 4);
|
||||
value =
|
||||
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(555.555F, value);
|
||||
|
||||
bits = Float.floatToRawIntBits(-555.555F);
|
||||
bytes = getBytes(bits, 4);
|
||||
value =
|
||||
Float4DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(-555.555F, value);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloat8Extremes() {
|
||||
|
||||
long bits = Double.doubleToRawLongBits(Double.NaN);
|
||||
byte[] bytes = getBytes(bits, 8);
|
||||
Object value =
|
||||
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(Double.NaN, value);
|
||||
|
||||
bits = Double.doubleToRawLongBits(Double.POSITIVE_INFINITY);
|
||||
bytes = getBytes(bits, 8);
|
||||
value =
|
||||
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(Double.POSITIVE_INFINITY, value);
|
||||
|
||||
bits = Double.doubleToRawLongBits(Double.NEGATIVE_INFINITY);
|
||||
bytes = getBytes(bits, 8);
|
||||
value =
|
||||
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(Double.NEGATIVE_INFINITY, value);
|
||||
|
||||
bits = Double.doubleToRawLongBits(0D);
|
||||
bytes = getBytes(bits, 8);
|
||||
value =
|
||||
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(0D, value);
|
||||
|
||||
bits = Double.doubleToRawLongBits(1D);
|
||||
bytes = getBytes(bits, 8);
|
||||
value =
|
||||
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(1D, value);
|
||||
|
||||
bits = Double.doubleToRawLongBits(-1D);
|
||||
bytes = getBytes(bits, 8);
|
||||
value =
|
||||
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(-1D, value);
|
||||
|
||||
bits = Double.doubleToRawLongBits(555.555D);
|
||||
bytes = getBytes(bits, 8);
|
||||
value =
|
||||
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(555.555D, value);
|
||||
|
||||
bits = Double.doubleToRawLongBits(-555.555D);
|
||||
bytes = getBytes(bits, 8);
|
||||
value =
|
||||
Float8DataType.dataType.getValue(new ByteMemBufferImpl(null, bytes, false), null, 10);
|
||||
assertEquals(-555.555D, value);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,310 @@
|
|||
/* ###
|
||||
* 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.program.model.data;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.docking.settings.SettingsImpl;
|
||||
|
||||
public class FunctionDefinitionDataTypeTest extends AbstractGenericTest {
|
||||
private StandAloneDataTypeManager dtm;
|
||||
private FunctionDefinition functionDt;
|
||||
private int transactionID;
|
||||
|
||||
private FunctionDefinition createFunctionDefinition(String name) {
|
||||
return (FunctionDefinition) dtm.resolve(new FunctionDefinitionDataType(name), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for FunctionDefinitionDataTypeTest.
|
||||
*/
|
||||
public FunctionDefinitionDataTypeTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see TestCase#setUp()
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
dtm = new StandAloneDataTypeManager("dummyDTM");
|
||||
transactionID = dtm.startTransaction("");
|
||||
functionDt = createFunctionDefinition("Test");
|
||||
}
|
||||
|
||||
/*
|
||||
* @see TestCase#tearDown()
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
dtm.endTransaction(transactionID, true);
|
||||
dtm.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_WithName() {
|
||||
FunctionDefinitionDataType impl;
|
||||
FunctionDefinition fdt;
|
||||
|
||||
// name
|
||||
impl = new FunctionDefinitionDataType("testFunctionDefinition");
|
||||
assertEquals(impl.getName(), "testFunctionDefinition");
|
||||
assertNull(impl.getComment());
|
||||
assertTrue(impl.getReturnType().isEquivalent(DataType.DEFAULT));
|
||||
assertEquals(impl.getArguments().length, 0);
|
||||
assertNull(impl.getDataTypeManager());
|
||||
assertEquals(impl.getMnemonic(new SettingsImpl(impl, null)),
|
||||
"undefined testFunctionDefinition(void)");
|
||||
assertEquals(impl.getPathName(), "/testFunctionDefinition");
|
||||
|
||||
fdt = (FunctionDefinition) dtm.resolve(impl, null);
|
||||
assertEquals(fdt.getName(), "testFunctionDefinition");
|
||||
assertNull(fdt.getComment());
|
||||
assertTrue(fdt.getReturnType().isEquivalent(DataType.DEFAULT));
|
||||
assertEquals(fdt.getArguments().length, 0);
|
||||
String fdtCat = fdt.getCategoryPath().getPath();
|
||||
String rootCat = CategoryPath.ROOT.getPath();
|
||||
assertEquals(fdtCat, rootCat);
|
||||
assertEquals(fdt.getDataTypeManager(), dtm);
|
||||
assertEquals(fdt.getMnemonic(new SettingsImpl(impl, null)),
|
||||
"undefined testFunctionDefinition(void)");
|
||||
assertEquals("/testFunctionDefinition", fdt.getPathName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_WithDtmName() throws Exception {
|
||||
FunctionDefinitionDataType impl;
|
||||
FunctionDefinition fdt;
|
||||
|
||||
// dtm, name
|
||||
impl = new FunctionDefinitionDataType("testFunctionDefinition");
|
||||
assertEquals(impl.getName(), "testFunctionDefinition");
|
||||
assertNull(impl.getComment());
|
||||
assertTrue(impl.getReturnType().isEquivalent(DataType.DEFAULT));
|
||||
assertEquals(impl.getArguments().length, 0);
|
||||
assertEquals(CategoryPath.ROOT, impl.getCategoryPath());
|
||||
assertEquals(impl.getMnemonic(new SettingsImpl(impl, null)),
|
||||
"undefined testFunctionDefinition(void)");
|
||||
assertEquals(impl.getPathName(), "/testFunctionDefinition");
|
||||
|
||||
fdt = (FunctionDefinition) dtm.resolve(impl, null);
|
||||
assertEquals(fdt.getName(), "testFunctionDefinition");
|
||||
assertNull(fdt.getComment());
|
||||
assertTrue(fdt.getReturnType().isEquivalent(DataType.DEFAULT));
|
||||
assertEquals(fdt.getArguments().length, 0);
|
||||
String fdtCat = fdt.getCategoryPath().getPath();
|
||||
String rootCat = CategoryPath.ROOT.getPath();
|
||||
assertEquals(fdtCat, rootCat);
|
||||
assertEquals(fdt.getDataTypeManager(), dtm);
|
||||
assertEquals(fdt.getMnemonic(new SettingsImpl(impl, null)),
|
||||
"undefined testFunctionDefinition(void)");
|
||||
assertEquals(fdt.getPathName(), "/testFunctionDefinition");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_WithFuncSig() {
|
||||
FunctionDefinitionDataType impl;
|
||||
FunctionDefinition fdt;
|
||||
FunctionDefinitionDataType sig = new FunctionDefinitionDataType("testFunctionSig");
|
||||
sig.setReturnType(DataType.VOID);
|
||||
// sig
|
||||
impl = new FunctionDefinitionDataType(sig);
|
||||
assertEquals(impl.getName(), "testFunctionSig");
|
||||
assertNull(impl.getComment());
|
||||
assertTrue(impl.getReturnType().isEquivalent(DataType.VOID));
|
||||
assertEquals(impl.getArguments().length, 0);
|
||||
assertNull(impl.getDataTypeManager());
|
||||
assertEquals("void testFunctionSig(void)", impl.getMnemonic(new SettingsImpl(impl, null)));
|
||||
assertEquals(impl.getPathName(), "/testFunctionSig");
|
||||
|
||||
fdt = (FunctionDefinition) dtm.resolve(impl, null);
|
||||
assertEquals(fdt.getName(), "testFunctionSig");
|
||||
assertNull(fdt.getComment());
|
||||
assertTrue(fdt.getReturnType().isEquivalent(DataType.VOID));
|
||||
assertEquals(fdt.getArguments().length, 0);
|
||||
String fdtCat = fdt.getCategoryPath().getPath();
|
||||
String rootCat = CategoryPath.ROOT.getPath();
|
||||
assertEquals(fdtCat, rootCat);
|
||||
assertEquals(fdt.getDataTypeManager(), dtm);
|
||||
assertEquals("void testFunctionSig(void)", fdt.getMnemonic(new SettingsImpl(impl, null)));
|
||||
assertEquals(fdt.getPathName(), "/testFunctionSig");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_WithDtmFuncSig() {
|
||||
FunctionDefinitionDataType impl;
|
||||
FunctionDefinition fdt;
|
||||
FunctionDefinitionDataType sig = new FunctionDefinitionDataType("testFunctionSig");
|
||||
sig.setReturnType(DataType.VOID);
|
||||
|
||||
// dtm, sig
|
||||
impl = new FunctionDefinitionDataType(sig);
|
||||
assertEquals(impl.getName(), "testFunctionSig");
|
||||
assertNull(impl.getComment());
|
||||
assertTrue(impl.getReturnType().isEquivalent(DataType.VOID));
|
||||
assertEquals(impl.getArguments().length, 0);
|
||||
assertEquals("void testFunctionSig(void)", impl.getMnemonic(new SettingsImpl(impl, null)));
|
||||
assertEquals(impl.getPathName(), "/testFunctionSig");
|
||||
|
||||
fdt = (FunctionDefinition) dtm.resolve(impl, null);
|
||||
assertEquals(fdt.getName(), "testFunctionSig");
|
||||
assertNull(fdt.getComment());
|
||||
assertTrue(fdt.getReturnType().isEquivalent(DataType.VOID));
|
||||
assertEquals(fdt.getArguments().length, 0);
|
||||
String fdtCat = fdt.getCategoryPath().getPath();
|
||||
String rootCat = CategoryPath.ROOT.getPath();
|
||||
assertEquals(fdtCat, rootCat);
|
||||
assertEquals(fdt.getDataTypeManager(), dtm);
|
||||
assertEquals("void testFunctionSig(void)", fdt.getMnemonic(new SettingsImpl(impl, null)));
|
||||
assertEquals(fdt.getPathName(), "/testFunctionSig");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_WithDtmNameFuncSig() {
|
||||
FunctionDefinitionDataType impl;
|
||||
FunctionDefinition fdt;
|
||||
FunctionDefinitionDataType sig = new FunctionDefinitionDataType("testFunctionSig");
|
||||
sig.setReturnType(DataType.VOID);
|
||||
|
||||
// dtm, name, sig
|
||||
impl = new FunctionDefinitionDataType(CategoryPath.ROOT, "testDtmNameSig", sig);
|
||||
assertEquals(impl.getName(), "testDtmNameSig");
|
||||
assertNull(impl.getComment());
|
||||
assertTrue(impl.getReturnType().isEquivalent(DataType.VOID));
|
||||
assertEquals(impl.getArguments().length, 0);
|
||||
assertEquals("void testDtmNameSig(void)", impl.getMnemonic(new SettingsImpl(impl, null)));
|
||||
assertEquals(impl.getPathName(), "/testDtmNameSig");
|
||||
|
||||
fdt = (FunctionDefinition) dtm.resolve(impl, null);
|
||||
assertEquals(fdt.getName(), "testDtmNameSig");
|
||||
assertNull(fdt.getComment());
|
||||
assertTrue(fdt.getReturnType().isEquivalent(DataType.VOID));
|
||||
assertEquals(fdt.getArguments().length, 0);
|
||||
String fdtCat = fdt.getCategoryPath().getPath();
|
||||
String rootCat = CategoryPath.ROOT.getPath();
|
||||
assertEquals(fdtCat, rootCat);
|
||||
assertEquals(fdt.getDataTypeManager(), dtm);
|
||||
assertEquals("void testDtmNameSig(void)", fdt.getMnemonic(new SettingsImpl(impl, null)));
|
||||
assertEquals(fdt.getPathName(), "/testDtmNameSig");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_WithFunctionDefDt() {
|
||||
FunctionDefinitionDataType impl;
|
||||
FunctionDefinition fdt;
|
||||
FunctionDefinitionDataType sig = new FunctionDefinitionDataType("testFunctionSig");
|
||||
sig.setReturnType(DataType.VOID);
|
||||
FunctionDefinitionDataType functionDefDt = new FunctionDefinitionDataType(sig);
|
||||
|
||||
// functionDataTypeImpl
|
||||
impl = new FunctionDefinitionDataType(functionDefDt);
|
||||
assertEquals(impl.getName(), "testFunctionSig");
|
||||
assertNull(impl.getComment());
|
||||
assertTrue(impl.getReturnType().isEquivalent(DataType.VOID));
|
||||
assertEquals(impl.getArguments().length, 0);
|
||||
assertNull(null, impl.getDataTypeManager());
|
||||
assertEquals("void testFunctionSig(void)", impl.getMnemonic(new SettingsImpl(impl, null)));
|
||||
assertEquals(impl.getPathName(), "/testFunctionSig");
|
||||
|
||||
fdt = (FunctionDefinition) dtm.resolve(impl, null);
|
||||
assertEquals(fdt.getName(), "testFunctionSig");
|
||||
assertNull(fdt.getComment());
|
||||
assertTrue(fdt.getReturnType().isEquivalent(DataType.VOID));
|
||||
assertEquals(fdt.getArguments().length, 0);
|
||||
String fdtCat = fdt.getCategoryPath().getPath();
|
||||
String rootCat = CategoryPath.ROOT.getPath();
|
||||
assertEquals(fdtCat, rootCat);
|
||||
assertEquals(fdt.getDataTypeManager(), dtm);
|
||||
assertEquals("void testFunctionSig(void)", fdt.getMnemonic(new SettingsImpl(impl, null)));
|
||||
assertEquals(fdt.getPathName(), "/testFunctionSig");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetArguments() throws Exception {
|
||||
ParameterDefinition[] parms = functionDt.getArguments();
|
||||
assertEquals(0, parms.length);
|
||||
addThreeArguments();
|
||||
parms = functionDt.getArguments();
|
||||
assertEquals(3, parms.length);
|
||||
assertTrue(parms[0].getDataType().isEquivalent(new ByteDataType()));
|
||||
assertTrue(parms[1].getDataType().isEquivalent(new FloatDataType()));
|
||||
assertTrue(parms[2].getDataType().isEquivalent(new CharDataType()));
|
||||
assertEquals(parms[0].getName(), "parm1");
|
||||
assertEquals(parms[1].getName(), "parm2");
|
||||
assertEquals(parms[2].getName(), "parm3");
|
||||
assertEquals(parms[0].getComment(), "this is first parm.");
|
||||
assertEquals(parms[1].getComment(), "this is second parm.");
|
||||
assertEquals(parms[2].getComment(), "this is third parm.");
|
||||
}
|
||||
|
||||
private void addThreeArguments() {
|
||||
ParameterDefinition[] newParms = new ParameterDefinition[3];
|
||||
newParms[0] =
|
||||
new ParameterDefinitionImpl("parm1", new ByteDataType(), "this is first parm.");
|
||||
newParms[1] =
|
||||
new ParameterDefinitionImpl("parm2", new FloatDataType(), "this is second parm.");
|
||||
newParms[2] =
|
||||
new ParameterDefinitionImpl("parm3", new CharDataType(), "this is third parm.");
|
||||
functionDt.setArguments(newParms);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetName() throws Exception {
|
||||
functionDt.setName("printf");
|
||||
assertEquals(functionDt.getName(), "printf");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetComment() throws Exception {
|
||||
functionDt.setComment("My test comment.");
|
||||
assertEquals(functionDt.getComment(), "My test comment.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetReturnType() {
|
||||
functionDt.setReturnType(new DWordDataType());
|
||||
assertTrue(functionDt.getReturnType().isEquivalent(new DWordDataType()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConflictsWithSpecialName() {
|
||||
|
||||
String name = "operator[]";
|
||||
|
||||
// Create two function definition datatypes with the same name but different signature
|
||||
FunctionDefinitionDataType impl1 = new FunctionDefinitionDataType(name);
|
||||
impl1.setReturnType(IntegerDataType.dataType);
|
||||
impl1.setArguments(new ParameterDefinition[] {
|
||||
new ParameterDefinitionImpl("x", IntegerDataType.dataType, null) });
|
||||
FunctionDefinitionDataType impl2 = new FunctionDefinitionDataType(name);
|
||||
impl2.setReturnType(VoidDataType.dataType);
|
||||
|
||||
// Resolve the two function definitions. They should not be equal, and the second
|
||||
// one should be a conflict
|
||||
FunctionDefinition fd1 = (FunctionDefinition) dtm.resolve(impl1, null);
|
||||
FunctionDefinition fd2 = (FunctionDefinition) dtm.resolve(impl2, null);
|
||||
Assert.assertNotEquals(fd1, fd2);
|
||||
assertTrue(fd2.getPrototypeString().contains(DataType.CONFLICT_SUFFIX));
|
||||
|
||||
// Resolve the second function definition again. It should not have created a new
|
||||
// function definition.
|
||||
FunctionDefinition fd3 = (FunctionDefinition) dtm.resolve(impl2, null);
|
||||
assertEquals(fd2, fd3);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,969 @@
|
|||
/* ###
|
||||
* 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.program.model.data;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import generic.test.AbstractGTest;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class StructureTest extends AbstractGTest {
|
||||
private Structure struct;
|
||||
|
||||
/**
|
||||
* @param arg0
|
||||
*/
|
||||
public StructureTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
private Structure createStructure(String name, int length) {
|
||||
return new StructureDataType(name, length);
|
||||
}
|
||||
|
||||
private Union createUnion(String name) {
|
||||
return new UnionDataType(name);
|
||||
}
|
||||
|
||||
private TypeDef createTypeDef(DataType dataType) {
|
||||
return new TypedefDataType(dataType.getName() + "TypeDef", dataType);
|
||||
}
|
||||
|
||||
private Array createArray(DataType dataType, int numElements) {
|
||||
return new ArrayDataType(dataType, numElements, dataType.getLength());
|
||||
}
|
||||
|
||||
private Pointer createPointer(DataType dataType, int length) {
|
||||
return new PointerDataType(dataType, length);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
struct = createStructure("TestStruct", 0);
|
||||
struct.add(new ByteDataType(), "field1", "Comment1");
|
||||
struct.add(new WordDataType(), null, "Comment2");
|
||||
struct.add(new DWordDataType(), "field3", null);
|
||||
struct.add(new ByteDataType(), "field4", "Comment4");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd() throws Exception {
|
||||
assertEquals(8, struct.getLength());
|
||||
assertEquals(4, struct.getNumComponents());
|
||||
|
||||
DataTypeComponent dtc = struct.getComponent(0);
|
||||
assertEquals(0, dtc.getOffset());
|
||||
assertEquals(0, dtc.getOrdinal());
|
||||
assertEquals("field1", dtc.getFieldName());
|
||||
assertEquals("Comment1", dtc.getComment());
|
||||
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(1);
|
||||
assertEquals(1, dtc.getOffset());
|
||||
assertEquals(1, dtc.getOrdinal());
|
||||
assertEquals("field_0x1", dtc.getDefaultFieldName());
|
||||
assertEquals(null, dtc.getFieldName());
|
||||
assertEquals("Comment2", dtc.getComment());
|
||||
assertEquals(WordDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(2);
|
||||
assertEquals(3, dtc.getOffset());
|
||||
assertEquals(2, dtc.getOrdinal());
|
||||
assertEquals("field3", dtc.getFieldName());
|
||||
assertEquals(null, dtc.getComment());
|
||||
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(3);
|
||||
assertEquals(7, dtc.getOffset());
|
||||
assertEquals(3, dtc.getOrdinal());
|
||||
assertEquals("field4", dtc.getFieldName());
|
||||
assertEquals("Comment4", dtc.getComment());
|
||||
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd2() throws Exception {
|
||||
struct = createStructure("Test", 10);
|
||||
|
||||
assertEquals(10, struct.getLength());
|
||||
assertEquals(10, struct.getNumComponents());
|
||||
|
||||
struct.add(new ByteDataType(), "field1", "Comment1");
|
||||
struct.add(new WordDataType(), null, "Comment2");
|
||||
struct.add(new DWordDataType(), "field3", null);
|
||||
struct.add(new ByteDataType(), "field4", "Comment4");
|
||||
|
||||
assertEquals(18, struct.getLength());
|
||||
assertEquals(14, struct.getNumComponents());
|
||||
|
||||
DataTypeComponent dtc = struct.getComponent(0);
|
||||
assertEquals(0, dtc.getOffset());
|
||||
assertEquals(0, dtc.getOrdinal());
|
||||
assertEquals("field_0x0", dtc.getDefaultFieldName());
|
||||
assertNull(dtc.getFieldName());
|
||||
assertNull(dtc.getComment());
|
||||
assertEquals(DataType.DEFAULT, dtc.getDataType());
|
||||
|
||||
dtc = struct.getComponent(1);
|
||||
assertEquals(1, dtc.getOffset());
|
||||
assertEquals(1, dtc.getOrdinal());
|
||||
assertEquals("field_0x1", dtc.getDefaultFieldName());
|
||||
assertNull(dtc.getFieldName());
|
||||
|
||||
assertEquals(null, dtc.getComment());
|
||||
assertEquals(DataType.DEFAULT, dtc.getDataType());
|
||||
|
||||
dtc = struct.getComponent(10);
|
||||
assertEquals(10, dtc.getOffset());
|
||||
assertEquals(10, dtc.getOrdinal());
|
||||
assertEquals("field1", dtc.getFieldName());
|
||||
assertEquals("Comment1", dtc.getComment());
|
||||
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(11);
|
||||
assertEquals(11, dtc.getOffset());
|
||||
assertEquals(11, dtc.getOrdinal());
|
||||
assertEquals("field_0xb", dtc.getDefaultFieldName());
|
||||
assertNull(dtc.getFieldName());
|
||||
|
||||
assertEquals("Comment2", dtc.getComment());
|
||||
assertEquals(WordDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(12);
|
||||
assertEquals(13, dtc.getOffset());
|
||||
assertEquals(12, dtc.getOrdinal());
|
||||
assertEquals("field3", dtc.getFieldName());
|
||||
assertEquals(null, dtc.getComment());
|
||||
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsert_beginning() {
|
||||
struct.insert(0, new FloatDataType());
|
||||
assertEquals(12, struct.getLength());
|
||||
assertEquals(5, struct.getNumComponents());
|
||||
|
||||
DataTypeComponent dtc = struct.getComponent(0);
|
||||
assertEquals(0, dtc.getOffset());
|
||||
assertEquals(0, dtc.getOrdinal());
|
||||
assertEquals("field_0x0", dtc.getDefaultFieldName());
|
||||
assertNull(dtc.getFieldName());
|
||||
assertNull(dtc.getComment());
|
||||
assertEquals(FloatDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(1);
|
||||
assertEquals(4, dtc.getOffset());
|
||||
assertEquals(1, dtc.getOrdinal());
|
||||
assertEquals("field1", dtc.getFieldName());
|
||||
assertEquals("Comment1", dtc.getComment());
|
||||
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(2);
|
||||
assertEquals(5, dtc.getOffset());
|
||||
assertEquals(2, dtc.getOrdinal());
|
||||
assertEquals("field_0x5", dtc.getDefaultFieldName());
|
||||
assertNull(dtc.getFieldName());
|
||||
assertEquals("Comment2", dtc.getComment());
|
||||
assertEquals(WordDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(3);
|
||||
assertEquals(7, dtc.getOffset());
|
||||
assertEquals(3, dtc.getOrdinal());
|
||||
assertEquals("field3", dtc.getFieldName());
|
||||
assertEquals(null, dtc.getComment());
|
||||
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(4);
|
||||
assertEquals(11, dtc.getOffset());
|
||||
assertEquals(4, dtc.getOrdinal());
|
||||
assertEquals("field4", dtc.getFieldName());
|
||||
assertEquals("Comment4", dtc.getComment());
|
||||
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsert_end() {
|
||||
|
||||
struct.insert(4, new FloatDataType());
|
||||
assertEquals(12, struct.getLength());
|
||||
assertEquals(5, struct.getNumComponents());
|
||||
|
||||
DataTypeComponent dtc = struct.getComponent(0);
|
||||
assertEquals(0, dtc.getOffset());
|
||||
assertEquals(0, dtc.getOrdinal());
|
||||
assertEquals("field1", dtc.getFieldName());
|
||||
assertEquals("Comment1", dtc.getComment());
|
||||
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(1);
|
||||
assertEquals(1, dtc.getOffset());
|
||||
assertEquals(1, dtc.getOrdinal());
|
||||
assertEquals("field_0x1", dtc.getDefaultFieldName());
|
||||
assertNull(dtc.getFieldName());
|
||||
assertEquals("Comment2", dtc.getComment());
|
||||
assertEquals(WordDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(2);
|
||||
assertEquals(3, dtc.getOffset());
|
||||
assertEquals(2, dtc.getOrdinal());
|
||||
assertEquals("field3", dtc.getFieldName());
|
||||
assertEquals(null, dtc.getComment());
|
||||
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(3);
|
||||
assertEquals(7, dtc.getOffset());
|
||||
assertEquals(3, dtc.getOrdinal());
|
||||
assertEquals("field4", dtc.getFieldName());
|
||||
assertEquals("Comment4", dtc.getComment());
|
||||
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(4);
|
||||
assertEquals(8, dtc.getOffset());
|
||||
assertEquals(4, dtc.getOrdinal());
|
||||
assertEquals("field_0x8", dtc.getDefaultFieldName());
|
||||
assertNull(dtc.getFieldName());
|
||||
assertEquals(null, dtc.getComment());
|
||||
assertEquals(FloatDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsert_middle() {
|
||||
|
||||
struct.insert(2, new FloatDataType());
|
||||
assertEquals(12, struct.getLength());
|
||||
assertEquals(5, struct.getNumComponents());
|
||||
|
||||
DataTypeComponent dtc = struct.getComponent(0);
|
||||
assertEquals(0, dtc.getOffset());
|
||||
assertEquals(0, dtc.getOrdinal());
|
||||
assertEquals("field1", dtc.getFieldName());
|
||||
assertEquals("Comment1", dtc.getComment());
|
||||
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(1);
|
||||
assertEquals(1, dtc.getOffset());
|
||||
assertEquals(1, dtc.getOrdinal());
|
||||
assertEquals("field_0x1", dtc.getDefaultFieldName());
|
||||
assertNull(dtc.getFieldName());
|
||||
assertEquals("Comment2", dtc.getComment());
|
||||
assertEquals(WordDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(2);
|
||||
assertEquals(3, dtc.getOffset());
|
||||
assertEquals(2, dtc.getOrdinal());
|
||||
assertEquals("field_0x3", dtc.getDefaultFieldName());
|
||||
assertNull(dtc.getFieldName());
|
||||
assertNull(dtc.getComment());
|
||||
assertEquals(FloatDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(3);
|
||||
assertEquals(7, dtc.getOffset());
|
||||
assertEquals(3, dtc.getOrdinal());
|
||||
assertEquals("field3", dtc.getFieldName());
|
||||
assertEquals(null, dtc.getComment());
|
||||
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
dtc = struct.getComponent(4);
|
||||
assertEquals(11, dtc.getOffset());
|
||||
assertEquals(4, dtc.getOrdinal());
|
||||
assertEquals("field4", dtc.getFieldName());
|
||||
assertEquals("Comment4", dtc.getComment());
|
||||
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertWithEmptySpace() {
|
||||
struct = createStructure("Test", 100);
|
||||
struct.insert(40, new ByteDataType());
|
||||
struct.insert(20, new WordDataType());
|
||||
|
||||
struct.insert(10, new FloatDataType());
|
||||
|
||||
assertEquals(107, struct.getLength());
|
||||
assertEquals(103, struct.getNumComponents());
|
||||
|
||||
DataTypeComponent[] comps = struct.getDefinedComponents();
|
||||
assertEquals(3, comps.length);
|
||||
|
||||
assertEquals(10, comps[0].getOffset());
|
||||
assertEquals(10, comps[0].getOrdinal());
|
||||
assertEquals(FloatDataType.class, comps[0].getDataType().getClass());
|
||||
|
||||
assertEquals(24, comps[1].getOffset());
|
||||
assertEquals(21, comps[1].getOrdinal());
|
||||
assertEquals(WordDataType.class, comps[1].getDataType().getClass());
|
||||
|
||||
assertEquals(46, comps[2].getOffset());
|
||||
assertEquals(42, comps[2].getOrdinal());
|
||||
assertEquals(ByteDataType.class, comps[2].getDataType().getClass());
|
||||
}
|
||||
|
||||
// test inserting at offset 0
|
||||
@Test
|
||||
public void testInsertAtOffset() {
|
||||
struct.insertAtOffset(0, new FloatDataType(), 4);
|
||||
assertEquals(12, struct.getLength());
|
||||
DataTypeComponent[] comps = struct.getDefinedComponents();
|
||||
|
||||
assertEquals(5, comps.length);
|
||||
|
||||
assertEquals(0, comps[0].getOffset());
|
||||
assertEquals(0, comps[0].getOrdinal());
|
||||
assertEquals(FloatDataType.class, comps[0].getDataType().getClass());
|
||||
|
||||
assertEquals(4, comps[1].getOffset());
|
||||
assertEquals(1, comps[1].getOrdinal());
|
||||
assertEquals(ByteDataType.class, comps[1].getDataType().getClass());
|
||||
|
||||
assertEquals(5, comps[2].getOffset());
|
||||
assertEquals(2, comps[2].getOrdinal());
|
||||
assertEquals(WordDataType.class, comps[2].getDataType().getClass());
|
||||
|
||||
assertEquals(7, comps[3].getOffset());
|
||||
assertEquals(3, comps[3].getOrdinal());
|
||||
assertEquals(DWordDataType.class, comps[3].getDataType().getClass());
|
||||
|
||||
}
|
||||
|
||||
// test inserting at offset 1
|
||||
@Test
|
||||
public void testInsertAtOffset1() {
|
||||
struct.insertAtOffset(1, new FloatDataType(), 4);
|
||||
assertEquals(12, struct.getLength());
|
||||
|
||||
DataTypeComponent[] comps = struct.getDefinedComponents();
|
||||
|
||||
assertEquals(5, comps.length);
|
||||
|
||||
assertEquals(0, comps[0].getOffset());
|
||||
assertEquals(0, comps[0].getOrdinal());
|
||||
assertEquals(ByteDataType.class, comps[0].getDataType().getClass());
|
||||
|
||||
assertEquals(1, comps[1].getOffset());
|
||||
assertEquals(1, comps[1].getOrdinal());
|
||||
assertEquals(FloatDataType.class, comps[1].getDataType().getClass());
|
||||
|
||||
assertEquals(5, comps[2].getOffset());
|
||||
assertEquals(2, comps[2].getOrdinal());
|
||||
assertEquals(WordDataType.class, comps[2].getDataType().getClass());
|
||||
|
||||
assertEquals(7, comps[3].getOffset());
|
||||
assertEquals(3, comps[3].getOrdinal());
|
||||
assertEquals(DWordDataType.class, comps[3].getDataType().getClass());
|
||||
|
||||
}
|
||||
|
||||
// test inserting at offset 1
|
||||
@Test
|
||||
public void testInsertAtOffset2() {
|
||||
struct.insertAtOffset(2, new FloatDataType(), 4);
|
||||
assertEquals(13, struct.getLength());
|
||||
|
||||
DataTypeComponent[] comps = struct.getDefinedComponents();
|
||||
|
||||
assertEquals(5, comps.length);
|
||||
|
||||
assertEquals(0, comps[0].getOffset());
|
||||
assertEquals(0, comps[0].getOrdinal());
|
||||
assertEquals(ByteDataType.class, comps[0].getDataType().getClass());
|
||||
|
||||
assertEquals(2, comps[1].getOffset());
|
||||
assertEquals(2, comps[1].getOrdinal());
|
||||
assertEquals(FloatDataType.class, comps[1].getDataType().getClass());
|
||||
|
||||
assertEquals(6, comps[2].getOffset());
|
||||
assertEquals(3, comps[2].getOrdinal());
|
||||
assertEquals(WordDataType.class, comps[2].getDataType().getClass());
|
||||
|
||||
assertEquals(8, comps[3].getOffset());
|
||||
assertEquals(4, comps[3].getOrdinal());
|
||||
assertEquals(DWordDataType.class, comps[3].getDataType().getClass());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertAtOffsetPastEnd() {
|
||||
struct.insertAtOffset(100, new FloatDataType(), 4);
|
||||
assertEquals(104, struct.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearComponent() {
|
||||
struct.clearComponent(0);
|
||||
assertEquals(8, struct.getLength());
|
||||
assertEquals(4, struct.getNumComponents());
|
||||
DataTypeComponent dtc = struct.getComponent(0);
|
||||
assertEquals(DataType.DEFAULT, dtc.getDataType());
|
||||
dtc = struct.getComponent(1);
|
||||
assertEquals(WordDataType.class, dtc.getDataType().getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearComponent1() {
|
||||
struct.clearComponent(1);
|
||||
assertEquals(8, struct.getLength());
|
||||
assertEquals(5, struct.getNumComponents());
|
||||
DataTypeComponent dtc = struct.getComponent(1);
|
||||
assertEquals(DataType.DEFAULT, dtc.getDataType());
|
||||
dtc = struct.getComponent(2);
|
||||
assertEquals(DataType.DEFAULT, dtc.getDataType());
|
||||
dtc = struct.getComponent(0);
|
||||
assertEquals(ByteDataType.class, dtc.getDataType().getClass());
|
||||
dtc = struct.getComponent(3);
|
||||
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
|
||||
assertEquals(3, dtc.getOrdinal());
|
||||
assertEquals(3, dtc.getOffset());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplace() { // bigger, no space below
|
||||
try {
|
||||
struct.replace(0, new QWordDataType(), 8);
|
||||
Assert.fail();
|
||||
}
|
||||
catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplace1() { // bigger, space below
|
||||
struct.insert(1, new QWordDataType());
|
||||
struct.clearComponent(1);
|
||||
assertEquals(16, struct.getLength());
|
||||
assertEquals(12, struct.getNumComponents());
|
||||
|
||||
struct.replace(0, new QWordDataType(), 8);
|
||||
assertEquals(16, struct.getLength());
|
||||
assertEquals(5, struct.getNumComponents());
|
||||
DataTypeComponent[] comps = struct.getDefinedComponents();
|
||||
assertEquals(9, comps[1].getOffset());
|
||||
assertEquals(2, comps[1].getOrdinal());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplace2() { // same size
|
||||
struct.replace(0, new CharDataType(), 1);
|
||||
assertEquals(8, struct.getLength());
|
||||
assertEquals(4, struct.getNumComponents());
|
||||
DataTypeComponent[] comps = struct.getDefinedComponents();
|
||||
assertEquals(CharDataType.class, comps[0].getDataType().getClass());
|
||||
assertEquals(1, comps[1].getOffset());
|
||||
assertEquals(1, comps[1].getOrdinal());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplace3() { // smaller
|
||||
struct.replace(1, new CharDataType(), 1);
|
||||
assertEquals(8, struct.getLength());
|
||||
assertEquals(5, struct.getNumComponents());
|
||||
DataTypeComponent[] comps = struct.getDefinedComponents();
|
||||
assertEquals(CharDataType.class, comps[1].getDataType().getClass());
|
||||
assertEquals(1, comps[1].getOffset());
|
||||
assertEquals(1, comps[1].getOrdinal());
|
||||
assertEquals(3, comps[2].getOffset());
|
||||
assertEquals(3, comps[2].getOrdinal());
|
||||
assertEquals(DWordDataType.class, comps[2].getDataType().getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete() {
|
||||
struct.delete(1);
|
||||
assertEquals(6, struct.getLength());
|
||||
assertEquals(3, struct.getNumComponents());
|
||||
DataTypeComponent[] comps = struct.getDefinedComponents();
|
||||
assertEquals(DWordDataType.class, comps[1].getDataType().getClass());
|
||||
assertEquals(1, comps[1].getOffset());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteAtOffset() {
|
||||
struct.deleteAtOffset(2);
|
||||
assertEquals(6, struct.getLength());
|
||||
assertEquals(3, struct.getNumComponents());
|
||||
DataTypeComponent[] comps = struct.getDefinedComponents();
|
||||
assertEquals(DWordDataType.class, comps[1].getDataType().getClass());
|
||||
assertEquals(1, comps[1].getOffset());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteAll() {
|
||||
|
||||
Structure s = new StructureDataType("test1", 0);
|
||||
s.add(new ByteDataType());
|
||||
s.add(new FloatDataType());
|
||||
|
||||
struct.add(s);
|
||||
s.deleteAll();
|
||||
assertEquals(1, s.getLength());
|
||||
assertTrue(s.isNotYetDefined());
|
||||
assertEquals(0, s.getNumComponents());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetComponents() {
|
||||
struct = createStructure("Test", 8);
|
||||
struct.insert(2, new ByteDataType(), 1, "field3", "Comment1");
|
||||
struct.insert(5, new WordDataType(), 2, null, "Comment2");
|
||||
struct.insert(7, new DWordDataType(), 4, "field8", null);
|
||||
assertEquals(15, struct.getLength());
|
||||
assertEquals(11, struct.getNumComponents());
|
||||
DataTypeComponent[] dtcs = struct.getComponents();
|
||||
assertEquals(11, dtcs.length);
|
||||
int offset = 0;
|
||||
for (int i = 0; i < 11; i++) {
|
||||
assertEquals(i, dtcs[i].getOrdinal());
|
||||
assertEquals(offset, dtcs[i].getOffset());
|
||||
offset += dtcs[i].getLength();
|
||||
}
|
||||
assertEquals(DataType.DEFAULT, dtcs[0].getDataType());
|
||||
assertEquals(DataType.DEFAULT, dtcs[1].getDataType());
|
||||
assertEquals(ByteDataType.class, dtcs[2].getDataType().getClass());
|
||||
assertEquals(DataType.DEFAULT, dtcs[3].getDataType());
|
||||
assertEquals(DataType.DEFAULT, dtcs[4].getDataType());
|
||||
assertEquals(WordDataType.class, dtcs[5].getDataType().getClass());
|
||||
assertEquals(DataType.DEFAULT, dtcs[6].getDataType());
|
||||
assertEquals(DWordDataType.class, dtcs[7].getDataType().getClass());
|
||||
assertEquals(DataType.DEFAULT, dtcs[8].getDataType());
|
||||
assertEquals(DataType.DEFAULT, dtcs[9].getDataType());
|
||||
assertEquals(DataType.DEFAULT, dtcs[10].getDataType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDefinedComponents() {
|
||||
struct = createStructure("Test", 8);
|
||||
struct.insert(2, new ByteDataType(), 1, "field3", "Comment1");
|
||||
struct.insert(5, new WordDataType(), 2, null, "Comment2");
|
||||
struct.insert(7, new DWordDataType(), 4, "field8", null);
|
||||
assertEquals(15, struct.getLength());
|
||||
assertEquals(11, struct.getNumComponents());
|
||||
DataTypeComponent[] dtcs = struct.getDefinedComponents();
|
||||
assertEquals(3, dtcs.length);
|
||||
|
||||
assertEquals(ByteDataType.class, dtcs[0].getDataType().getClass());
|
||||
assertEquals(2, dtcs[0].getOrdinal());
|
||||
assertEquals(2, dtcs[0].getOffset());
|
||||
|
||||
assertEquals(WordDataType.class, dtcs[1].getDataType().getClass());
|
||||
assertEquals(5, dtcs[1].getOrdinal());
|
||||
assertEquals(5, dtcs[1].getOffset());
|
||||
|
||||
assertEquals(DWordDataType.class, dtcs[2].getDataType().getClass());
|
||||
assertEquals(7, dtcs[2].getOrdinal());
|
||||
assertEquals(8, dtcs[2].getOffset());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetComponentAt() {
|
||||
DataTypeComponent dtc = struct.getComponentAt(4);
|
||||
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
|
||||
assertEquals(2, dtc.getOrdinal());
|
||||
assertEquals(3, dtc.getOffset());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDataTypeAt() {
|
||||
Structure s1 = createStructure("Test1", 0);
|
||||
s1.add(new WordDataType());
|
||||
s1.add(struct);
|
||||
s1.add(new ByteDataType());
|
||||
|
||||
DataTypeComponent dtc = s1.getComponentAt(7);
|
||||
assertEquals(struct, dtc.getDataType());
|
||||
dtc = s1.getDataTypeAt(7);
|
||||
assertEquals(DWordDataType.class, dtc.getDataType().getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplaceWith() {
|
||||
assertEquals(8, struct.getLength());
|
||||
assertEquals(4, struct.getNumComponents());
|
||||
|
||||
Structure newStruct = createStructure("Replaced", 8);
|
||||
newStruct.setDescription("testReplaceWith()");
|
||||
DataTypeComponent dtc0 = newStruct.insert(2, new ByteDataType(), 1, "field3", "Comment1");
|
||||
DataTypeComponent dtc1 = newStruct.insert(5, new WordDataType(), 2, null, "Comment2");
|
||||
DataTypeComponent dtc2 = newStruct.insert(7, new DWordDataType(), 4, "field8", null);
|
||||
|
||||
struct.replaceWith(newStruct);
|
||||
assertEquals(15, struct.getLength());
|
||||
assertEquals(11, struct.getNumComponents());
|
||||
DataTypeComponent[] dtcs = struct.getDefinedComponents();
|
||||
assertEquals(3, dtcs.length);
|
||||
assertEquals(dtc0, dtcs[0]);
|
||||
assertEquals(dtc1, dtcs[1]);
|
||||
assertEquals(dtc2, dtcs[2]);
|
||||
assertEquals("TestStruct", struct.getName());
|
||||
assertEquals("", struct.getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a structure can't ... ???
|
||||
*/
|
||||
@Test
|
||||
public void testCyclingProblem() {
|
||||
Structure newStruct = createStructure("TestStruct", 80);
|
||||
newStruct.setDescription("testReplaceWith()");
|
||||
newStruct.add(new ByteDataType(), "field0", "Comment1");
|
||||
newStruct.add(struct, "field1", null);
|
||||
newStruct.add(new WordDataType(), null, "Comment2");
|
||||
newStruct.add(new DWordDataType(), "field3", null);
|
||||
|
||||
try {
|
||||
struct.add(newStruct);
|
||||
Assert.fail();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
}
|
||||
try {
|
||||
struct.insert(0, newStruct);
|
||||
Assert.fail();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
}
|
||||
try {
|
||||
struct.replace(0, newStruct, newStruct.getLength());
|
||||
Assert.fail();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a structure can't be added to itself.
|
||||
*/
|
||||
@Test
|
||||
public void testCyclicDependencyProblem1() {
|
||||
try {
|
||||
struct.add(struct);
|
||||
Assert.fail("Shouldn't be able to add a structure to itself.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from adding the struct to itself.
|
||||
}
|
||||
try {
|
||||
struct.insert(0, struct);
|
||||
Assert.fail("Shouldn't be able to insert a structure into itself.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from inserting the struct to itself.
|
||||
}
|
||||
try {
|
||||
struct.replace(0, struct, struct.getLength());
|
||||
Assert.fail(
|
||||
"Shouldn't be able to replace a structure component with the structure itself.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from replacing the struct to itself.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a structure array can't be added to the same structure.
|
||||
*/
|
||||
@Test
|
||||
public void testCyclicDependencyProblem2() {
|
||||
Array array = createArray(struct, 3);
|
||||
try {
|
||||
struct.add(array);
|
||||
Assert.fail("Shouldn't be able to add a structure array to the same structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from adding the struct to itself.
|
||||
}
|
||||
try {
|
||||
struct.insert(0, array);
|
||||
Assert.fail("Shouldn't be able to insert a structure array into the same structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from inserting the struct to itself.
|
||||
}
|
||||
try {
|
||||
struct.replace(0, array, array.getLength());
|
||||
Assert.fail(
|
||||
"Shouldn't be able to replace a structure component with an array of the same structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from replacing the struct to itself.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a typedef of a structure can't be added to the structure.
|
||||
*/
|
||||
@Test
|
||||
public void testCyclicDependencyProblem3() {
|
||||
TypeDef typeDef = createTypeDef(struct);
|
||||
try {
|
||||
struct.add(typeDef);
|
||||
Assert.fail("Shouldn't be able to add a structure typedef to the typedef's structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from adding the struct to itself.
|
||||
}
|
||||
try {
|
||||
struct.insert(0, typeDef);
|
||||
Assert.fail(
|
||||
"Shouldn't be able to insert a structure typedef into the typedef's structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from inserting the struct to itself.
|
||||
}
|
||||
try {
|
||||
struct.replace(0, typeDef, typeDef.getLength());
|
||||
Assert.fail(
|
||||
"Shouldn't be able to replace a structure component with the structure's typedef.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from replacing the struct to itself.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a structure can't contain another structure that contains it.
|
||||
*/
|
||||
@Test
|
||||
public void testCyclicDependencyProblem4() {
|
||||
Structure anotherStruct = createStructure("AnotherStruct", 0);
|
||||
anotherStruct.add(struct);
|
||||
try {
|
||||
struct.add(anotherStruct);
|
||||
Assert.fail(
|
||||
"Shouldn't be able to add another structure, which contains this structure, to this structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from adding the struct to itself.
|
||||
}
|
||||
try {
|
||||
struct.insert(0, anotherStruct);
|
||||
Assert.fail(
|
||||
"Shouldn't be able to insert another structure, which contains this structure, to this structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from inserting the struct to itself.
|
||||
}
|
||||
try {
|
||||
struct.replace(0, anotherStruct, anotherStruct.getLength());
|
||||
Assert.fail(
|
||||
"Shouldn't be able to replace a structure component with another structure which contains this structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from replacing the struct to itself.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a structure can't contain another structure that contains a typedef to it.
|
||||
*/
|
||||
@Test
|
||||
public void testCyclicDependencyProblem5() {
|
||||
Structure anotherStruct = createStructure("AnotherStruct", 0);
|
||||
TypeDef typeDef = createTypeDef(struct);
|
||||
anotherStruct.add(typeDef);
|
||||
try {
|
||||
struct.add(anotherStruct);
|
||||
Assert.fail(
|
||||
"Shouldn't be able to add another structure, which contains a typedef of this structure, to this structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from adding the struct to itself.
|
||||
}
|
||||
try {
|
||||
struct.insert(0, anotherStruct);
|
||||
Assert.fail(
|
||||
"Shouldn't be able to insert another structure, which contains a typedef of this structure, to this structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from inserting the struct to itself.
|
||||
}
|
||||
try {
|
||||
struct.replace(0, anotherStruct, anotherStruct.getLength());
|
||||
Assert.fail(
|
||||
"Shouldn't be able to replace a structure component with another structure which contains a typedef of this structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from replacing the struct to itself.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a structure can't contain a union that contains that structure.
|
||||
*/
|
||||
@Test
|
||||
public void testCyclicDependencyProblem6() {
|
||||
Union union = createUnion("TestUnion");
|
||||
union.add(struct);
|
||||
try {
|
||||
struct.add(union);
|
||||
Assert.fail(
|
||||
"Shouldn't be able to add a union, which contains this structure, to this structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from adding the struct to itself.
|
||||
}
|
||||
try {
|
||||
struct.insert(0, union);
|
||||
Assert.fail(
|
||||
"Shouldn't be able to insert a union, which contains this structure, to this structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from inserting the struct to itself.
|
||||
}
|
||||
try {
|
||||
struct.replace(0, union, union.getLength());
|
||||
Assert.fail(
|
||||
"Shouldn't be able to replace a structure component with a union, which contains this structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from replacing the struct to itself.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a structure can't contain a typedef of a union that contains that structure.
|
||||
*/
|
||||
@Test
|
||||
public void testCyclicDependencyProblem7() {
|
||||
Union union = createUnion("TestUnion");
|
||||
union.add(struct);
|
||||
TypeDef typeDef = createTypeDef(union);
|
||||
try {
|
||||
struct.add(typeDef);
|
||||
Assert.fail(
|
||||
"Shouldn't be able to add a typedef of a union, which contains this structure, to this structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from adding the union typedef to the struct.
|
||||
}
|
||||
try {
|
||||
struct.insert(0, typeDef);
|
||||
Assert.fail(
|
||||
"Shouldn't be able to insert a typedef of a union, which contains this structure, to this structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from inserting the union typedef to the struct.
|
||||
}
|
||||
try {
|
||||
struct.replace(0, typeDef, typeDef.getLength());
|
||||
Assert.fail(
|
||||
"Shouldn't be able to replace a structure component with a typedef of a union, which contains this structure.");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// Should get an exception from replacing the struct component with the union typedef.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a structure can contain a pointer in it to the same structure.
|
||||
*/
|
||||
@Test
|
||||
public void testNoCyclicDependencyProblemForStructurePointer() {
|
||||
Pointer structurePointer = createPointer(struct, 4);
|
||||
try {
|
||||
struct.add(structurePointer);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
Assert.fail("Should be able to add a structure pointer to the pointer's structure.");
|
||||
}
|
||||
try {
|
||||
struct.insert(0, structurePointer);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
Assert.fail(
|
||||
"Should be able to insert a structure pointer into the pointer's structure.");
|
||||
}
|
||||
try {
|
||||
struct.replace(0, structurePointer, structurePointer.getLength());
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
Assert.fail(
|
||||
"Should be able to replace a structure component with the structure's pointer.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a structure can contain a pointer in it to a typedef of the same structure.
|
||||
*/
|
||||
@Test
|
||||
public void testNoCyclicDependencyProblemForTypedefPointer() {
|
||||
TypeDef typeDef = createTypeDef(struct);
|
||||
Pointer typedefPointer = createPointer(typeDef, 4);
|
||||
try {
|
||||
struct.add(typedefPointer);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
Assert.fail(
|
||||
"Should be able to add a structure typedef pointer to the pointer's structure.");
|
||||
}
|
||||
try {
|
||||
struct.insert(0, typedefPointer);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
Assert.fail(
|
||||
"Should be able to insert a structure typedef pointer into the pointer's structure.");
|
||||
}
|
||||
try {
|
||||
struct.replace(0, typedefPointer, typedefPointer.getLength());
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
Assert.fail(
|
||||
"Should be able to replace a structure component with the structure's typedef pointer.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a structure can contain a pointer in it to a typedef of the same structure.
|
||||
*/
|
||||
@Test
|
||||
public void testNoCyclicDependencyProblemForArrayPointer() {
|
||||
TypeDef typeDef = createTypeDef(struct);
|
||||
Array array = createArray(typeDef, 5);
|
||||
Pointer arrayPointer = createPointer(array, 4);
|
||||
try {
|
||||
struct.add(arrayPointer);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
Assert.fail(
|
||||
"Should be able to add a structure typedef array pointer to the pointer's structure.");
|
||||
}
|
||||
try {
|
||||
struct.insert(0, arrayPointer);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
Assert.fail(
|
||||
"Should be able to insert a structure typedef arrayointer into the pointer's structure.");
|
||||
}
|
||||
try {
|
||||
struct.replace(0, arrayPointer, arrayPointer.getLength());
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
Assert.fail(
|
||||
"Should be able to replace a structure component with the structure's typedef array pointer.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,448 @@
|
|||
/* ###
|
||||
* 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.program.model.data;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class UnionTest extends AbstractGenericTest {
|
||||
private DataTypeManager dtm;
|
||||
private Union union;
|
||||
private int id;
|
||||
|
||||
private Union createUnion(String name) {
|
||||
Union unionDt = new UnionDataType(name);
|
||||
return (Union)dtm.addDataType(unionDt,DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
}
|
||||
|
||||
private Structure createStructure(String name, int size) {
|
||||
return (Structure)dtm.addDataType(new StructureDataType(name, size),DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
}
|
||||
|
||||
private TypeDef createTypeDef(DataType dataType) {
|
||||
return new TypedefDataType(dataType.getName()+"TypeDef", dataType);
|
||||
}
|
||||
|
||||
private Array createArray(DataType dataType, int numElements) {
|
||||
return new ArrayDataType(dataType, numElements, dataType.getLength());
|
||||
}
|
||||
|
||||
private Pointer createPointer(DataType dataType, int length) {
|
||||
return new PointerDataType(dataType, length);
|
||||
}
|
||||
/**
|
||||
* Constructor for UnionTest.
|
||||
* @param arg0
|
||||
*/
|
||||
public UnionTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
/*
|
||||
* @see TestCase#setUp()
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
dtm = new StandAloneDataTypeManager("dummyDTM");
|
||||
id = dtm.startTransaction("");
|
||||
union = createUnion("TestUnion");
|
||||
union.add(new ByteDataType(), "field1", "Comment1");
|
||||
union.add(new WordDataType(), null, "Comment2");
|
||||
union.add(new DWordDataType(), "field3", null);
|
||||
union.add(new ByteDataType(), "field4", "Comment4");
|
||||
}
|
||||
|
||||
/*
|
||||
* @see TestCase#tearDown()
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
dtm.endTransaction(id, true);
|
||||
dtm.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd() throws Exception {
|
||||
assertEquals(4, union.getLength());
|
||||
assertEquals(4, union.getNumComponents());
|
||||
|
||||
DataTypeComponent[] dtcs = union.getComponents();
|
||||
assertEquals(4, dtcs.length);
|
||||
DataTypeComponent dtc = union.getComponent(3);
|
||||
assertEquals("field4", dtc.getFieldName());
|
||||
assertEquals("byte", dtc.getDataType().getName());
|
||||
|
||||
Structure struct = new StructureDataType("struct_1", 0);
|
||||
struct.add(new ByteDataType());
|
||||
struct.add(new StringDataType(), 10);
|
||||
|
||||
union.add(struct);
|
||||
assertEquals(struct.getLength(), union.getLength());
|
||||
}
|
||||
@Test
|
||||
public void testAdd2() {
|
||||
Structure struct = createStructure("struct_1", 0);
|
||||
struct.add(new ByteDataType());
|
||||
struct.add(new StringDataType(), 10);
|
||||
|
||||
union.add(struct);
|
||||
union.delete(4);
|
||||
assertEquals(4, union.getNumComponents());
|
||||
assertEquals(4, union.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetComponent() {
|
||||
Structure struct = createStructure("struct_1", 0);
|
||||
struct.add(new ByteDataType());
|
||||
struct.add(new StringDataType(), 10);
|
||||
DataTypeComponent newdtc = union.add(struct, "field5", "comments");
|
||||
DataTypeComponent dtc = union.getComponent(4);
|
||||
assertEquals(newdtc, dtc);
|
||||
assertEquals("field5", dtc.getFieldName());
|
||||
assertEquals("comments", dtc.getComment());
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testGetComponents() {
|
||||
Structure struct = createStructure("struct_1", 0);
|
||||
struct.add(new ByteDataType());
|
||||
struct.add(new StringDataType(), 10);
|
||||
union.add(struct, "field5", "comments");
|
||||
DataTypeComponent[] dtcs = union.getComponents();
|
||||
assertEquals(5, dtcs.length);
|
||||
|
||||
assertEquals(5, union.getNumComponents());
|
||||
}
|
||||
@Test
|
||||
public void testInsert() {
|
||||
Structure struct = createStructure("struct_1", 0);
|
||||
struct.add(new ByteDataType());
|
||||
struct.add(new StringDataType(), 10);
|
||||
|
||||
DataTypeComponent dtc = union.getComponent(2);
|
||||
assertEquals("field3", dtc.getFieldName());
|
||||
|
||||
union.insert(2, struct, struct.getLength(), "field5", "field5 comments");
|
||||
assertEquals(11, union.getLength());
|
||||
dtc = union.getComponent(2);
|
||||
assertEquals("field5", dtc.getFieldName());
|
||||
}
|
||||
@Test
|
||||
public void testGetName() {
|
||||
assertEquals("TestUnion", union.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloneRetainIdentity() throws Exception {
|
||||
Union unionCopy = (Union)union.clone(null);
|
||||
assertNull(unionCopy.getDataTypeManager());
|
||||
assertEquals(4, union.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCopyDontRetain() throws Exception {
|
||||
Union unionCopy = (Union)union.copy(null);
|
||||
assertNull(unionCopy.getDataTypeManager());
|
||||
assertEquals(4, union.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete() throws Exception {
|
||||
Structure struct = createStructure("struct_1", 0);
|
||||
struct.add(new ByteDataType());
|
||||
struct.add(new StringDataType(), 10);
|
||||
union.add(struct);
|
||||
assertEquals(11, union.getLength());
|
||||
|
||||
union.delete(4);
|
||||
assertEquals(4, union.getLength());
|
||||
|
||||
union.delete(2);
|
||||
assertEquals(2, union.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPartOf() {
|
||||
Structure struct = createStructure("struct_1", 0);
|
||||
struct.add(new ByteDataType());
|
||||
DataTypeComponent dtc = struct.add(createStructure("mystring", 10));
|
||||
DataType dt = dtc.getDataType();
|
||||
DataTypeComponent newdtc = union.add(struct);
|
||||
assertTrue(union.isPartOf(dt));
|
||||
|
||||
Structure newstruct = (Structure)newdtc.getDataType();
|
||||
Structure s1 = (Structure)newstruct.add(createStructure("s1", 1)).getDataType();
|
||||
dt = s1.add(new QWordDataType()).getDataType();
|
||||
|
||||
assertTrue(union.isPartOf(dt));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplaceWith() {
|
||||
assertEquals(4, union.getLength());
|
||||
assertEquals(4, union.getNumComponents());
|
||||
|
||||
Union newUnion = createUnion("Replaced");
|
||||
newUnion.setDescription("testReplaceWith()");
|
||||
DataTypeComponent dtc2 = newUnion.insert(0, new DWordDataType(), 4, "field2", null);
|
||||
DataTypeComponent dtc1 = newUnion.insert(0, new WordDataType(), 2, null, "Comment2");
|
||||
DataTypeComponent dtc0 = newUnion.insert(0, new ByteDataType(), 1, "field0", "Comment1");
|
||||
|
||||
union.replaceWith(newUnion);
|
||||
assertEquals(4, union.getLength());
|
||||
assertEquals(3, union.getNumComponents());
|
||||
DataTypeComponent[] dtcs = union.getComponents();
|
||||
assertEquals(3, dtcs.length);
|
||||
assertEquals(dtc0, dtcs[0]);
|
||||
assertEquals(dtc1, dtcs[1]);
|
||||
assertEquals(dtc2, dtcs[2]);
|
||||
assertEquals("TestUnion", union.getName());
|
||||
assertEquals("testReplaceWith()", union.getDescription());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCyclingProblem() {
|
||||
Union newUnion = createUnion("Test");
|
||||
newUnion.setDescription("testReplaceWith()");
|
||||
newUnion.add(new ByteDataType(), "field0", "Comment1");
|
||||
newUnion.add(union, "field1", null);
|
||||
newUnion.add(new WordDataType(), null, "Comment2");
|
||||
newUnion.add(new DWordDataType(), "field3", null);
|
||||
|
||||
try {
|
||||
union.add(newUnion);
|
||||
Assert.fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
try {
|
||||
union.insert(0, newUnion);
|
||||
Assert.fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a structure can't be added to itself.
|
||||
*/
|
||||
@Test
|
||||
public void testCyclicDependencyProblem1() {
|
||||
try {
|
||||
union.add(union);
|
||||
Assert.fail("Shouldn't be able to add a union to itself.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Should get an exception from adding the union to itself.
|
||||
}
|
||||
try {
|
||||
union.insert(0, union);
|
||||
Assert.fail("Shouldn't be able to insert a union into itself.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Should get an exception from inserting the union to itself.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a structure array can't be added to the same structure.
|
||||
*/
|
||||
@Test
|
||||
public void testCyclicDependencyProblem2() {
|
||||
Array array = createArray(union, 3);
|
||||
try {
|
||||
union.add(array);
|
||||
Assert.fail("Shouldn't be able to add a union array to the same union.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Should get an exception from adding the union to itself.
|
||||
}
|
||||
try {
|
||||
union.insert(0, array);
|
||||
Assert.fail("Shouldn't be able to insert a union array into the same union.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Should get an exception from inserting the union to itself.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a typedef of a union can't be added to the union.
|
||||
*/
|
||||
@Test
|
||||
public void testCyclicDependencyProblem3() {
|
||||
TypeDef typeDef = createTypeDef(union);
|
||||
try {
|
||||
union.add(typeDef);
|
||||
Assert.fail("Shouldn't be able to add a union typedef to the typedef's union.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Should get an exception from adding the union to itself.
|
||||
}
|
||||
try {
|
||||
union.insert(0, typeDef);
|
||||
Assert.fail("Shouldn't be able to insert a union typedef into the typedef's union.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Should get an exception from inserting the union to itself.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a union can't contain another union that contains it.
|
||||
*/
|
||||
@Test
|
||||
public void testCyclicDependencyProblem4() {
|
||||
Union anotherUnion = createUnion("AnotherUnion");
|
||||
anotherUnion.add(union);
|
||||
try {
|
||||
union.add(anotherUnion);
|
||||
Assert.fail("Shouldn't be able to add another union, which contains this union, to this union.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Should get an exception from adding the union to itself.
|
||||
}
|
||||
try {
|
||||
union.insert(0, anotherUnion);
|
||||
Assert.fail("Shouldn't be able to insert another union, which contains this union, to this union.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Should get an exception from inserting the union to itself.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a union can't contain another union that contains a typedef to it.
|
||||
*/
|
||||
@Test
|
||||
public void testCyclicDependencyProblem5() {
|
||||
Union anotherUnion = createUnion("AnotherUnion");
|
||||
TypeDef typeDef = createTypeDef(union);
|
||||
anotherUnion.add(typeDef);
|
||||
try {
|
||||
union.add(anotherUnion);
|
||||
Assert.fail("Shouldn't be able to add another union, which contains a typedef of this union, to this union.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Should get an exception from adding the union to itself.
|
||||
}
|
||||
try {
|
||||
union.insert(0, anotherUnion);
|
||||
Assert.fail("Shouldn't be able to insert another union, which contains a typedef of this union, to this union.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Should get an exception from inserting the union to itself.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a union can't contain a structure that contains that union.
|
||||
*/
|
||||
@Test
|
||||
public void testCyclicDependencyProblem6() {
|
||||
Union structure = createUnion("TestStructure");
|
||||
structure.add(union);
|
||||
try {
|
||||
union.add(structure);
|
||||
Assert.fail("Shouldn't be able to add a structure, which contains this union, to this union.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Should get an exception from adding the union to itself.
|
||||
}
|
||||
try {
|
||||
union.insert(0, structure);
|
||||
Assert.fail("Shouldn't be able to insert a structure, which contains this union, to this union.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Should get an exception from inserting the union to itself.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a structure can't contain a typedef of a union that contains that structure.
|
||||
*/
|
||||
@Test
|
||||
public void testCyclicDependencyProblem7() {
|
||||
Structure structure = createStructure("TestStructure", 0);
|
||||
structure.add(union);
|
||||
TypeDef typeDef = createTypeDef(structure);
|
||||
try {
|
||||
union.add(typeDef);
|
||||
Assert.fail("Shouldn't be able to add a typedef of a strucutre, which contains this union, to this union.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Should get an exception from adding the structure typedef to the union.
|
||||
}
|
||||
try {
|
||||
union.insert(0, typeDef);
|
||||
Assert.fail("Shouldn't be able to insert a typedef of a structure, which contains this union, to this union.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Should get an exception from inserting the structure typedef to the union.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a structure can contain a pointer in it to the same structure.
|
||||
*/
|
||||
@Test
|
||||
public void testNoCyclicDependencyProblemForStructurePointer() {
|
||||
Pointer unionPointer = createPointer(union, 4);
|
||||
try {
|
||||
union.add(unionPointer);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Assert.fail("Should be able to add a union pointer to the pointer's union.");
|
||||
}
|
||||
try {
|
||||
union.insert(0, unionPointer);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Assert.fail("Should be able to insert a union pointer into the pointer's union.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a union can contain a pointer in it to a typedef of the same union.
|
||||
*/
|
||||
@Test
|
||||
public void testNoCyclicDependencyProblemForTypedefPointer() {
|
||||
TypeDef typeDef = createTypeDef(union);
|
||||
Pointer typedefPointer = createPointer(typeDef, 4);
|
||||
try {
|
||||
union.add(typedefPointer);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Assert.fail("Should be able to add a union typedef pointer to the pointer's union.");
|
||||
}
|
||||
try {
|
||||
union.insert(0, typedefPointer);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Assert.fail("Should be able to insert a union typedef pointer into the pointer's union.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a union can contain a pointer in it to a typedef of the same union.
|
||||
*/
|
||||
@Test
|
||||
public void testNoCyclicDependencyProblemForArrayPointer() {
|
||||
TypeDef typeDef = createTypeDef(union);
|
||||
Array array = createArray(typeDef, 5);
|
||||
Pointer arrayPointer = createPointer(array, 4);
|
||||
try {
|
||||
union.add(arrayPointer);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Assert.fail("Should be able to add a union typedef array pointer to the pointer's union.");
|
||||
}
|
||||
try {
|
||||
union.insert(0, arrayPointer);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Assert.fail("Should be able to insert a union typedef array pointer into the pointer's union.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
|
||||
|
||||
<appender name="console" class="org.apache.log4j.ConsoleAppender">
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="%-5p %c{1}: %m%n"/>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<logger name="ghidra.sleigh.grammar.SleighPreprocessor">
|
||||
<level value="DEBUG"/>
|
||||
</logger>
|
||||
|
||||
<logger name="slgh_compile.SleighCompile">
|
||||
<level value="DEBUG"/>
|
||||
</logger>
|
||||
|
||||
<root>
|
||||
<priority value="TRACE"/>
|
||||
<appender-ref ref="console"/>
|
||||
</root>
|
||||
|
||||
</log4j:configuration>
|
Loading…
Add table
Add a link
Reference in a new issue