mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GP-5421 Ensure merge inserts structure components in the correct
sequence to account for zero-length overlapping components. Refactor how dataTypeDeleted and dataTypeReplaced are handled. Use blocking error message popup during most Merge operations.
This commit is contained in:
parent
dcc87e7fb7
commit
fe944640b9
45 changed files with 2427 additions and 1795 deletions
|
@ -226,27 +226,33 @@ public abstract class MergeManager implements DomainObjectMergeManager {
|
|||
return merge(TaskMonitor.DUMMY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a blocking error popup. When used from a {@link MergeResolver} task it will
|
||||
* prevent that task from exiting/progressing until the error popup is dismissed.
|
||||
* @param title popup title
|
||||
* @param msg error message
|
||||
*/
|
||||
public static void showBlockingError(String title, String msg) {
|
||||
Swing.runNow(() -> Msg.showError(MergeManager.class, null, title, msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a blocking error popup. When used from a {@link MergeResolver} task it will
|
||||
* prevent that task from exiting/progressing until the error popup is dismissed.
|
||||
* @param title popup title
|
||||
* @param msg error message
|
||||
* @param e exception
|
||||
*/
|
||||
public static void showBlockingError(String title, String msg, Exception e) {
|
||||
Swing.runNow(() -> Msg.showError(MergeManager.class, null, title, msg, e));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the apply button according to the "enabled" parameter.
|
||||
*/
|
||||
@Override
|
||||
public void setApplyEnabled(final boolean enabled) {
|
||||
Runnable r = () -> mergePlugin.setApplyEnabled(enabled);
|
||||
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
r.run();
|
||||
}
|
||||
else {
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(r);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
Msg.showError(this, null, "Error in Merge Dialog",
|
||||
"Error setting enablement for Apply button", e);
|
||||
}
|
||||
}
|
||||
Swing.runNow(() -> mergePlugin.setApplyEnabled(enabled));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -440,13 +446,8 @@ public abstract class MergeManager implements DomainObjectMergeManager {
|
|||
|
||||
}
|
||||
catch (final Exception e) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Msg.showError(this, null, "Error During Merge",
|
||||
"Error occurred in " + mergeResolvers[currentIndex].getName(), e);
|
||||
}
|
||||
});
|
||||
MergeManager.showBlockingError("Error During Merge",
|
||||
"Error occurred in " + mergeResolvers[currentIndex].getName(), e);
|
||||
mergeStatus = false;
|
||||
conflictsResolveCompleted();
|
||||
}
|
||||
|
@ -457,16 +458,6 @@ public abstract class MergeManager implements DomainObjectMergeManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display error message dialog in a blocking fashion.
|
||||
* @param originator message originator
|
||||
* @param title dialog title
|
||||
* @param msg dialog message
|
||||
*/
|
||||
public static void displayErrorAndWait(Object originator, String title, String msg) {
|
||||
Swing.runNow(() -> Msg.showError(originator, null, title, msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Block until the user completes the current merge operation, or
|
||||
* cancels the merge process.
|
||||
|
|
|
@ -41,6 +41,7 @@ import ghidra.program.model.listing.ProgramChangeSet;
|
|||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
import ghidra.util.HelpLocation;
|
||||
import ghidra.util.SystemUtilities;
|
||||
import help.Help;
|
||||
import help.HelpService;
|
||||
|
||||
|
@ -54,25 +55,19 @@ public class ProgramMultiUserMergeManager extends MergeManager {
|
|||
private GoToAddressLabelPlugin goToPlugin;
|
||||
private ListingMergePanel mergePanel;
|
||||
private boolean isShowingListingMergePanel = false;
|
||||
private boolean showListingPanels = true;
|
||||
MergeNavigatable navigatable;
|
||||
|
||||
private final boolean showListingPanels;
|
||||
|
||||
public ProgramMultiUserMergeManager(Program resultProgram, Program myProgram,
|
||||
Program originalProgram, Program latestProgram, ProgramChangeSet latestChangeSet,
|
||||
ProgramChangeSet myChangeSet) {
|
||||
super(resultProgram, myProgram, originalProgram, latestProgram, latestChangeSet,
|
||||
myChangeSet);
|
||||
}
|
||||
|
||||
public ProgramMultiUserMergeManager(Program resultProgram, Program myProgram,
|
||||
Program originalProgram, Program latestProgram, ProgramChangeSet latestChangeSet,
|
||||
ProgramChangeSet myChangeSet, boolean showListingPanels) {
|
||||
super(resultProgram, myProgram, originalProgram, latestProgram, latestChangeSet,
|
||||
myChangeSet);
|
||||
|
||||
// True signals to show the Listing panels (the default); false signals to leave the
|
||||
// panels empty.
|
||||
this.showListingPanels = showListingPanels;
|
||||
// Disable multi-listing panel rendering when running in batch test mode for
|
||||
// improved performance.
|
||||
showListingPanels = !SystemUtilities.isInTestingBatchMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -27,8 +27,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
|
||||
import docking.widgets.dialogs.ReadTextDialog;
|
||||
import generic.stl.Pair;
|
||||
import ghidra.app.merge.MergeConstants;
|
||||
import ghidra.app.merge.ProgramMultiUserMergeManager;
|
||||
import ghidra.app.merge.*;
|
||||
import ghidra.app.merge.tool.ListingMergePanel;
|
||||
import ghidra.app.merge.util.ConflictUtility;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
|
@ -267,9 +266,7 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
|||
switch (type) {
|
||||
case FUNC_RETURN_ADDRESS_OFFSET:
|
||||
return (latestStack.getReturnAddressOffset() == myStack
|
||||
.getReturnAddressOffset())
|
||||
? 0
|
||||
: type;
|
||||
.getReturnAddressOffset()) ? 0 : type;
|
||||
// For now, we are not allowing you to set the parameter offset or local size outright.
|
||||
// case FUNC_PARAMETER_OFFSET:
|
||||
// return (latestStack.getParameterOffset() == myStack.getParameterOffset()) ? 0
|
||||
|
@ -278,9 +275,7 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
|||
// return (latestStack.getLocalSize() == myStack.getLocalSize()) ? 0 : type;
|
||||
case FUNC_STACK_PURGE_SIZE:
|
||||
return (functions[LATEST].getStackPurgeSize() == functions[MY]
|
||||
.getStackPurgeSize())
|
||||
? 0
|
||||
: type;
|
||||
.getStackPurgeSize()) ? 0 : type;
|
||||
case FUNC_NAME:
|
||||
return hasUnresolvedFunctionNameConflict(functions, monitor) ? type : 0;
|
||||
case FUNC_INLINE:
|
||||
|
@ -294,13 +289,10 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
|||
// : type;
|
||||
case FUNC_CALLING_CONVENTION:
|
||||
return (functions[LATEST].getCallingConventionName()
|
||||
.equals(
|
||||
functions[MY].getCallingConventionName())) ? 0 : type;
|
||||
.equals(functions[MY].getCallingConventionName())) ? 0 : type;
|
||||
case FUNC_SIGNATURE_SOURCE:
|
||||
return (functions[LATEST].getSignatureSource() == functions[MY]
|
||||
.getSignatureSource())
|
||||
? 0
|
||||
: type;
|
||||
.getSignatureSource()) ? 0 : type;
|
||||
default:
|
||||
throw new IllegalArgumentException("type = " + type);
|
||||
}
|
||||
|
@ -1372,10 +1364,8 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
|||
|
||||
protected void mergeParamInfo(Address entryPt, List<ParamInfoConflict> paramInfoConflicts,
|
||||
int chosenConflictOption, TaskMonitor monitor) throws CancelledException {
|
||||
Iterator<ParamInfoConflict> iter = paramInfoConflicts.iterator();
|
||||
while (iter.hasNext()) {
|
||||
for (ParamInfoConflict pc : paramInfoConflicts) {
|
||||
monitor.checkCancelled();
|
||||
ParamInfoConflict pc = iter.next();
|
||||
mergeParamInfo(entryPt, pc, chosenConflictOption, monitor);
|
||||
}
|
||||
}
|
||||
|
@ -1404,10 +1394,8 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
|||
protected void mergeParamInfo(Function[] functions, List<ParamInfoConflict> paramInfoConflicts,
|
||||
int chosenConflictOption, TaskMonitor monitor) throws CancelledException {
|
||||
|
||||
Iterator<ParamInfoConflict> iter = paramInfoConflicts.iterator();
|
||||
while (iter.hasNext()) {
|
||||
for (ParamInfoConflict pc : paramInfoConflicts) {
|
||||
monitor.checkCancelled();
|
||||
ParamInfoConflict pc = iter.next();
|
||||
mergeParamInfo(functions, pc, chosenConflictOption, monitor);
|
||||
}
|
||||
}
|
||||
|
@ -1435,10 +1423,8 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
|||
|
||||
protected void mergeLocals(Address entryPt, List<LocalVariableConflict> localVarConflicts,
|
||||
int chosenConflictOption, TaskMonitor monitor) throws CancelledException {
|
||||
Iterator<LocalVariableConflict> iter = localVarConflicts.iterator();
|
||||
while (iter.hasNext()) {
|
||||
for (LocalVariableConflict lvc : localVarConflicts) {
|
||||
monitor.checkCancelled();
|
||||
LocalVariableConflict lvc = iter.next();
|
||||
mergeLocal(entryPt, lvc, chosenConflictOption, monitor);
|
||||
}
|
||||
}
|
||||
|
@ -1629,7 +1615,7 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
|||
final Address entryPt, final TaskMonitor monitor) {
|
||||
|
||||
if (conflictPanel == null) {
|
||||
Msg.showError(this, null, "Error Displaying Conflict Panel",
|
||||
MergeManager.showBlockingError("Error Displaying Conflict Panel",
|
||||
"The conflict panel could not be created.");
|
||||
return;
|
||||
}
|
||||
|
@ -1666,8 +1652,7 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
|||
private void showConflictPanelException(final Address entryPt, Exception e) {
|
||||
String message = "Couldn't display conflict for function at " + entryPt.toString(true) +
|
||||
".\n " + e.getMessage();
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(), "Function Merge Error",
|
||||
message, e);
|
||||
MergeManager.showBlockingError("Function Merge Error", message, e);
|
||||
// Should this just put a message on errorBuf instead?
|
||||
}
|
||||
|
||||
|
@ -1990,16 +1975,13 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
|||
}
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Setting Function Namespace", e.getMessage());
|
||||
MergeManager.showBlockingError("Error Setting Function Namespace", e.getMessage());
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Setting Function Namespace", e.getMessage());
|
||||
MergeManager.showBlockingError("Error Setting Function Namespace", e.getMessage());
|
||||
}
|
||||
catch (CircularDependencyException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Setting Function Namespace", e.getMessage());
|
||||
MergeManager.showBlockingError("Error Setting Function Namespace", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2141,8 +2123,8 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
|||
final TaskMonitor monitor) {
|
||||
|
||||
if (functions[RESULT] == null) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Creating Function Conflict Panel", "RESULT function is null.");
|
||||
MergeManager.showBlockingError("Error Creating Function Conflict Panel",
|
||||
"RESULT function is null.");
|
||||
return null;
|
||||
}
|
||||
Address myEntryPoint = functions[MY].getEntryPoint();
|
||||
|
@ -2157,8 +2139,7 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
|||
conflictCount = funcConflicts.get(myEntryPoint);
|
||||
}
|
||||
catch (NoValueException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Creating Function Conflict Panel",
|
||||
MergeManager.showBlockingError("Error Creating Function Conflict Panel",
|
||||
"Couldn't get conflict information for MY function at " +
|
||||
myEntryPoint.toString(true) + ".");
|
||||
return null;
|
||||
|
@ -2306,9 +2287,11 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
|||
getReturnInfo(programs[LATEST],
|
||||
getReturnString(functions[LATEST], hasCustomerStorage), "Use ", " version"),
|
||||
LATEST_BUTTON_NAME, KEEP_LATEST, changeListener);
|
||||
verticalConflictPanel.addRadioButtonRow(getReturnInfo(programs[MY],
|
||||
getReturnString(functions[MY], hasCustomerStorage), "Use ", " version"),
|
||||
CHECKED_OUT_BUTTON_NAME, KEEP_MY, changeListener);
|
||||
verticalConflictPanel
|
||||
.addRadioButtonRow(
|
||||
getReturnInfo(programs[MY],
|
||||
getReturnString(functions[MY], hasCustomerStorage), "Use ", " version"),
|
||||
CHECKED_OUT_BUTTON_NAME, KEEP_MY, changeListener);
|
||||
verticalConflictPanel.addInfoRow(getReturnInfo(programs[ORIGINAL],
|
||||
getReturnString(functions[ORIGINAL], hasCustomerStorage), "", " version"));
|
||||
|
||||
|
@ -2351,7 +2334,7 @@ abstract class AbstractFunctionMerger implements ListingMergeConstants {
|
|||
String msg = "Failed to resolve variable '" +
|
||||
((lvc.vars[ORIGINAL_VAR] != null) ? lvc.vars[ORIGINAL_VAR].getName() : "") +
|
||||
"'.";
|
||||
Msg.showError(this, null, "Resolve Variable Error", msg, e1);
|
||||
MergeManager.showBlockingError("Resolve Variable Error", msg, e1);
|
||||
}
|
||||
showResolveInfo(getInfoTitle());
|
||||
}
|
||||
|
|
|
@ -15,23 +15,23 @@
|
|||
*/
|
||||
package ghidra.app.merge.listing;
|
||||
|
||||
import ghidra.app.merge.tool.ListingMergePanel;
|
||||
import ghidra.app.merge.util.ConflictUtility;
|
||||
import ghidra.app.merge.util.MergeUtilities;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.util.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import ghidra.app.merge.MergeManager;
|
||||
import ghidra.app.merge.tool.ListingMergePanel;
|
||||
import ghidra.app.merge.util.ConflictUtility;
|
||||
import ghidra.app.merge.util.MergeUtilities;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.CommentType;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.util.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* Class for merging comment changes. This class can merge non-conflicting
|
||||
* comment changes that were made to the checked out version. It can determine
|
||||
|
@ -87,6 +87,7 @@ class CommentMerger extends AbstractListingMerger {
|
|||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.ListingMerger#getConflictType()
|
||||
*/
|
||||
@Override
|
||||
public String getConflictType() {
|
||||
return "Comment";
|
||||
}
|
||||
|
@ -107,6 +108,7 @@ class CommentMerger extends AbstractListingMerger {
|
|||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.ListingMerger#autoMerge(ghidra.util.task.TaskMonitor)
|
||||
*/
|
||||
@Override
|
||||
public void autoMerge(int progressMin, int progressMax, TaskMonitor monitor)
|
||||
throws ProgramConflictException, MemoryAccessException, CancelledException {
|
||||
|
||||
|
@ -133,9 +135,8 @@ class CommentMerger extends AbstractListingMerger {
|
|||
|
||||
private void autoMerge(int diffType, AddressSet conflictSet, TaskMonitor monitor)
|
||||
throws ProgramConflictException, CancelledException {
|
||||
AddressSetView latestDetailSet =
|
||||
listingMergeMgr.diffOriginalLatest.getDifferences(new ProgramDiffFilter(diffType),
|
||||
monitor);
|
||||
AddressSetView latestDetailSet = listingMergeMgr.diffOriginalLatest
|
||||
.getDifferences(new ProgramDiffFilter(diffType), monitor);
|
||||
AddressSetView myDetailSet =
|
||||
listingMergeMgr.diffOriginalMy.getDifferences(new ProgramDiffFilter(diffType), monitor);
|
||||
AddressSet autoSet = new AddressSet();
|
||||
|
@ -175,6 +176,7 @@ class CommentMerger extends AbstractListingMerger {
|
|||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.ListingMerger#hasConflict(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public boolean hasConflict(Address addr) {
|
||||
return hasConflict(addr, ProgramMergeFilter.PLATE_COMMENTS) ||
|
||||
hasConflict(addr, ProgramMergeFilter.PRE_COMMENTS) ||
|
||||
|
@ -186,6 +188,7 @@ class CommentMerger extends AbstractListingMerger {
|
|||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.ListingMerger#getConflictCount(ghidra.program.model.address.Address)
|
||||
*/
|
||||
@Override
|
||||
public int getConflictCount(Address addr) {
|
||||
int count = 0;
|
||||
if (hasConflict(addr, ProgramMergeFilter.PLATE_COMMENTS)) {
|
||||
|
@ -216,7 +219,7 @@ class CommentMerger extends AbstractListingMerger {
|
|||
else {
|
||||
conflictPanel.clear();
|
||||
}
|
||||
int type = getCodeUnitCommentType(programMergeType);
|
||||
CommentType type = getCodeUnitCommentType(programMergeType);
|
||||
int choice = getChoiceForCommentType(programMergeType);
|
||||
boolean useForAll = (choice != ASK_USER);
|
||||
conflictPanel.setUseForAll(useForAll);
|
||||
|
@ -234,9 +237,8 @@ class CommentMerger extends AbstractListingMerger {
|
|||
String msg;
|
||||
conflictPanel.setRowHeader(new String[] { "Option", "Comment" });
|
||||
if (latestComment == null || myComment == null) {
|
||||
String[] latestStrings =
|
||||
new String[] { createButtonText(LATEST_TITLE, programMergeType, latestComment),
|
||||
latestTrunc };
|
||||
String[] latestStrings = new String[] {
|
||||
createButtonText(LATEST_TITLE, programMergeType, latestComment), latestTrunc };
|
||||
String[] myStrings =
|
||||
new String[] { createButtonText(MY_TITLE, programMergeType, myComment), myTrunc };
|
||||
conflictPanel.addRadioButtonRow(latestStrings, LATEST_BUTTON_NAME, KEEP_LATEST,
|
||||
|
@ -246,20 +248,19 @@ class CommentMerger extends AbstractListingMerger {
|
|||
msg = conflictTypeText + " comments differ. Select whether or not to keep the comment.";
|
||||
}
|
||||
else {
|
||||
String[] latestStrings =
|
||||
new String[] { createCheckBoxText(LATEST_TITLE, programMergeType, latestComment),
|
||||
latestTrunc };
|
||||
String[] latestStrings = new String[] {
|
||||
createCheckBoxText(LATEST_TITLE, programMergeType, latestComment), latestTrunc };
|
||||
String[] myStrings =
|
||||
new String[] { createCheckBoxText(MY_TITLE, programMergeType, myComment), myTrunc };
|
||||
conflictPanel.addCheckBoxRow(latestStrings, LATEST_CHECK_BOX_NAME, KEEP_LATEST,
|
||||
changeListener);
|
||||
conflictPanel.addCheckBoxRow(myStrings, CHECKED_OUT_CHECK_BOX_NAME, KEEP_MY,
|
||||
changeListener);
|
||||
msg =
|
||||
getTypeName(programMergeType) +
|
||||
" comments differ. Select either or both of the comments.";
|
||||
msg = getTypeName(programMergeType) +
|
||||
" comments differ. Select either or both of the comments.";
|
||||
}
|
||||
conflictPanel.addInfoRow(new String[] { "'" + ORIGINAL_TITLE + "' version", originalTrunc });
|
||||
conflictPanel
|
||||
.addInfoRow(new String[] { "'" + ORIGINAL_TITLE + "' version", originalTrunc });
|
||||
conflictPanel.setHeader(msg);
|
||||
|
||||
}
|
||||
|
@ -267,9 +268,10 @@ class CommentMerger extends AbstractListingMerger {
|
|||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.ListingMerger#mergeConflicts(ghidra.app.merge.tool.ListingMergePanel, ghidra.program.model.address.Address, int, ghidra.util.task.TaskMonitor)
|
||||
*/
|
||||
@Override
|
||||
public void mergeConflicts(ListingMergePanel listingPanel, Address addr,
|
||||
int chosenConflictOption, TaskMonitor monitor) throws CancelledException,
|
||||
MemoryAccessException {
|
||||
int chosenConflictOption, TaskMonitor monitor)
|
||||
throws CancelledException, MemoryAccessException {
|
||||
mergeConflicts(ProgramMergeFilter.PLATE_COMMENTS, listingPanel, addr, chosenConflictOption,
|
||||
monitor);
|
||||
mergeConflicts(ProgramMergeFilter.PRE_COMMENTS, listingPanel, addr, chosenConflictOption,
|
||||
|
@ -287,8 +289,8 @@ class CommentMerger extends AbstractListingMerger {
|
|||
if (!hasConflict(addr, programMergeFilterCommentType)) {
|
||||
return;
|
||||
}
|
||||
monitor.setMessage("Resolving " + getTypeName(programMergeFilterCommentType) +
|
||||
" Comment conflicts.");
|
||||
monitor.setMessage(
|
||||
"Resolving " + getTypeName(programMergeFilterCommentType) + " Comment conflicts.");
|
||||
int choiceForCommentType = getChoiceForCommentType(programMergeFilterCommentType);
|
||||
if (choiceForCommentType != ASK_USER) {
|
||||
merge(addr, programMergeFilterCommentType, choiceForCommentType, monitor);
|
||||
|
@ -323,20 +325,20 @@ class CommentMerger extends AbstractListingMerger {
|
|||
}
|
||||
}
|
||||
|
||||
private int getCodeUnitCommentType(int programMergeCommentType) {
|
||||
private CommentType getCodeUnitCommentType(int programMergeCommentType) {
|
||||
switch (programMergeCommentType) {
|
||||
case ProgramMergeFilter.PLATE_COMMENTS:
|
||||
return CodeUnit.PLATE_COMMENT;
|
||||
return CommentType.PLATE;
|
||||
case ProgramMergeFilter.PRE_COMMENTS:
|
||||
return CodeUnit.PRE_COMMENT;
|
||||
return CommentType.PRE;
|
||||
case ProgramMergeFilter.EOL_COMMENTS:
|
||||
return CodeUnit.EOL_COMMENT;
|
||||
return CommentType.EOL;
|
||||
case ProgramMergeFilter.REPEATABLE_COMMENTS:
|
||||
return CodeUnit.REPEATABLE_COMMENT;
|
||||
return CommentType.REPEATABLE;
|
||||
case ProgramMergeFilter.POST_COMMENTS:
|
||||
return CodeUnit.POST_COMMENT;
|
||||
return CommentType.POST;
|
||||
default:
|
||||
return -1;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,7 +394,7 @@ class CommentMerger extends AbstractListingMerger {
|
|||
postCommentChoice = choiceForCommentType;
|
||||
break;
|
||||
default:
|
||||
Msg.showError(this, listingMergePanel, "Unrecognized Comment Type",
|
||||
MergeManager.showBlockingError("Unrecognized Comment Type",
|
||||
"Unrecognized indicator (" + programMergeCommentType +
|
||||
") for comment type to merge.");
|
||||
}
|
||||
|
@ -405,6 +407,7 @@ class CommentMerger extends AbstractListingMerger {
|
|||
this.currentMonitor = monitor;
|
||||
try {
|
||||
final ChangeListener changeListener = new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
conflictOption = conflictPanel.getSelectedOptions();
|
||||
if (conflictOption == ASK_USER) {
|
||||
|
@ -432,6 +435,7 @@ class CommentMerger extends AbstractListingMerger {
|
|||
}
|
||||
};
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setupConflictsPanel(listingPanel, CommentMerger.this.currentAddress,
|
||||
CommentMerger.this.programMergeType, changeListener);
|
||||
|
@ -439,6 +443,7 @@ class CommentMerger extends AbstractListingMerger {
|
|||
}
|
||||
});
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Address addressToShow = CommentMerger.this.currentAddress;
|
||||
listingPanel.clearAllBackgrounds();
|
||||
|
@ -506,6 +511,7 @@ class CommentMerger extends AbstractListingMerger {
|
|||
/* (non-Javadoc)
|
||||
* @see ghidra.app.merge.listing.ListingMerger#getConflicts()
|
||||
*/
|
||||
@Override
|
||||
public AddressSetView getConflicts() {
|
||||
AddressSet conflicts = new AddressSet();
|
||||
conflicts.add(conflictPlate);
|
||||
|
|
|
@ -15,16 +15,15 @@
|
|||
*/
|
||||
package ghidra.app.merge.listing;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import generic.stl.Pair;
|
||||
import ghidra.app.merge.MergeConstants;
|
||||
import ghidra.app.merge.MergeManager;
|
||||
import ghidra.app.merge.tool.ListingMergePanel;
|
||||
import ghidra.app.merge.util.ConflictUtility;
|
||||
import ghidra.app.util.NamespaceUtils;
|
||||
|
@ -436,7 +435,7 @@ public class ExternalFunctionMerger extends AbstractFunctionMerger implements Li
|
|||
thunkChoice = choiceForFunctionConflict;
|
||||
break;
|
||||
default:
|
||||
Msg.showError(this, listingMergePanel, "Unrecognized External Conflict Type",
|
||||
MergeManager.showBlockingError("Unrecognized External Conflict Type",
|
||||
"Unrecognized indicator (" + externalConflictType +
|
||||
") for external conflict type to merge.");
|
||||
}
|
||||
|
@ -1246,12 +1245,10 @@ public class ExternalFunctionMerger extends AbstractFunctionMerger implements Li
|
|||
originalResolvedSymbols.put(originalID, resultID);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Merging External Location", e.getMessage());
|
||||
MergeManager.showBlockingError("Error Merging External Location", e.getMessage());
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Merging External Location", e.getMessage());
|
||||
MergeManager.showBlockingError("Error Merging External Location", e.getMessage());
|
||||
}
|
||||
|
||||
mergeManager.updateProgress((++changeNum / totalChanges) * 100);
|
||||
|
@ -1392,8 +1389,7 @@ public class ExternalFunctionMerger extends AbstractFunctionMerger implements Li
|
|||
ExternalLocation chosenExternalLocation;
|
||||
if ((chosenConflictOption & KEEP_ORIGINAL) != 0) {
|
||||
// chosenExternalLocation = externalLocations[ORIGINAL];
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Merging External Location",
|
||||
MergeManager.showBlockingError("Error Merging External Location",
|
||||
"Can't currently merge external data type from ORIGINAL program." +
|
||||
((externalLocations[ORIGINAL] != null)
|
||||
? (" ORIGINAL external was " + externalLocations[ORIGINAL].getLabel() +
|
||||
|
@ -1409,8 +1405,7 @@ public class ExternalFunctionMerger extends AbstractFunctionMerger implements Li
|
|||
}
|
||||
else {
|
||||
// chosenExternalLocation = null;
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Merging External Location",
|
||||
MergeManager.showBlockingError("Error Merging External Location",
|
||||
"Can only merge external data type from LATEST or MY program." +
|
||||
((externalLocations[RESULT] != null)
|
||||
? (" RESULT external was " + externalLocations[RESULT].getLabel() + ".")
|
||||
|
@ -3376,14 +3371,14 @@ public class ExternalFunctionMerger extends AbstractFunctionMerger implements Li
|
|||
resultExternalLocation = addExternal(myExternalLocation, monitor);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Merging External Location", "Couldn't merge external '" +
|
||||
myExternalLocation.getLabel() + "'. " + e.getMessage());
|
||||
MergeManager.showBlockingError("Error Merging External Location",
|
||||
"Couldn't merge external '" + myExternalLocation.getLabel() + "'. " +
|
||||
e.getMessage());
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Merging External Location", "Couldn't merge external '" +
|
||||
myExternalLocation.getLabel() + "'. " + e.getMessage());
|
||||
MergeManager.showBlockingError("Error Merging External Location",
|
||||
"Couldn't merge external '" + myExternalLocation.getLabel() + "'. " +
|
||||
e.getMessage());
|
||||
}
|
||||
return resultExternalLocation;
|
||||
}
|
||||
|
@ -3742,12 +3737,10 @@ public class ExternalFunctionMerger extends AbstractFunctionMerger implements Li
|
|||
}
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Merging External Location", e.getMessage());
|
||||
MergeManager.showBlockingError("Error Merging External Location", e.getMessage());
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Merging External Location", e.getMessage());
|
||||
MergeManager.showBlockingError("Error Merging External Location", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4087,17 +4080,8 @@ public class ExternalFunctionMerger extends AbstractFunctionMerger implements Li
|
|||
this.currentMonitor = monitor;
|
||||
this.currentConflictPanel = (ConflictPanel) conflictPanel;
|
||||
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(() -> addConflictPanel.setBottomComponent(conflictPanel));
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Msg.showError(this, null, "Error Displaying Conflict Panel", e);
|
||||
return;
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
Msg.showError(this, null, "Error Displaying Conflict Panel", e);
|
||||
return;
|
||||
}
|
||||
Swing.runNow(() -> addConflictPanel.setBottomComponent(conflictPanel));
|
||||
|
||||
if (mergeManager != null) {
|
||||
mergeManager.setApplyEnabled(false);
|
||||
addConflictPanel.setConflictInfo(conflictIndex, latestLocation, myLocation);
|
||||
|
@ -4123,7 +4107,7 @@ public class ExternalFunctionMerger extends AbstractFunctionMerger implements Li
|
|||
final TaskMonitor monitor) {
|
||||
|
||||
if (conflictPanel == null) {
|
||||
Msg.showError(this, null, "Error Displaying Conflict Panel",
|
||||
MergeManager.showBlockingError("Error Displaying Conflict Panel",
|
||||
"The conflict panel could not be created.");
|
||||
return;
|
||||
}
|
||||
|
@ -4131,23 +4115,8 @@ public class ExternalFunctionMerger extends AbstractFunctionMerger implements Li
|
|||
this.currentMonitor = monitor;
|
||||
this.currentConflictPanel = conflictPanel;
|
||||
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(() -> listingPanel.setBottomComponent(conflictPanel));
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
// Set background color of function entry point code unit
|
||||
// listingPanel.clearAllBackgrounds();
|
||||
// listingPanel.paintAllBackgrounds(new AddressSet(resultAddressFactory,
|
||||
// entryPtAddr, entryPtAddr));
|
||||
});
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
Msg.showError(this, null, "Error Displaying Conflict Panel", e);
|
||||
return;
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
Msg.showError(this, null, "Error Displaying Conflict Panel", e);
|
||||
return;
|
||||
}
|
||||
Swing.runNow(() -> listingPanel.setBottomComponent(conflictPanel));
|
||||
|
||||
if (mergeManager != null) {
|
||||
mergeManager.setApplyEnabled(false);
|
||||
|
||||
|
|
|
@ -170,8 +170,8 @@ public class ExternalProgramMerger implements MergeResolver, ListingMergeConstan
|
|||
String title = getConflictType() + " Merge Information";
|
||||
String msg = infoBuf.toString();
|
||||
ReadTextDialog dialog = new ReadTextDialog(title, msg);
|
||||
mergeManager.getMergeTool().showDialog(dialog,
|
||||
mergeManager.getMergeTool().getToolFrame());
|
||||
mergeManager.getMergeTool()
|
||||
.showDialog(dialog, mergeManager.getMergeTool().getToolFrame());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -195,11 +195,11 @@ public class ExternalProgramMerger implements MergeResolver, ListingMergeConstan
|
|||
|
||||
if (mergeManager != null) {
|
||||
latestResolvedSymbols = (LongLongHashtable) mergeManager
|
||||
.getResolveInformation(MergeConstants.RESOLVED_LATEST_SYMBOLS);
|
||||
.getResolveInformation(MergeConstants.RESOLVED_LATEST_SYMBOLS);
|
||||
myResolvedSymbols = (LongLongHashtable) mergeManager
|
||||
.getResolveInformation(MergeConstants.RESOLVED_MY_SYMBOLS);
|
||||
.getResolveInformation(MergeConstants.RESOLVED_MY_SYMBOLS);
|
||||
originalResolvedSymbols = (LongLongHashtable) mergeManager
|
||||
.getResolveInformation(MergeConstants.RESOLVED_ORIGINAL_SYMBOLS);
|
||||
.getResolveInformation(MergeConstants.RESOLVED_ORIGINAL_SYMBOLS);
|
||||
|
||||
// Populate the reverse maps.
|
||||
mapResultsToOriginalLibs();
|
||||
|
@ -913,7 +913,7 @@ public class ExternalProgramMerger implements MergeResolver, ListingMergeConstan
|
|||
isExternalUserDefined(program2, libName2));
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
Msg.showError(this, null, "Error Setting External Program Name",
|
||||
MergeManager.showBlockingError("Error Setting External Program Name",
|
||||
"Couldn't set path to '" + em2.getExternalLibraryPath(libName2) +
|
||||
"' for external program name '" + libName2 + "'");
|
||||
}
|
||||
|
@ -922,7 +922,7 @@ public class ExternalProgramMerger implements MergeResolver, ListingMergeConstan
|
|||
if (libName1 != null && em1.contains(libName1)) {
|
||||
boolean removed = em1.removeExternalLibrary(libName1);
|
||||
if (!removed) {
|
||||
Msg.showError(this, null, "Error Removing External Program Name",
|
||||
MergeManager.showBlockingError("Error Removing External Program Name",
|
||||
"Couldn't remove external program name '" + libName1 + "'");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import javax.swing.event.ChangeListener;
|
|||
|
||||
import generic.stl.Pair;
|
||||
import ghidra.app.merge.MergeConstants;
|
||||
import ghidra.app.merge.MergeManager;
|
||||
import ghidra.app.merge.tool.ListingMergePanel;
|
||||
import ghidra.app.merge.util.ConflictUtility;
|
||||
import ghidra.app.merge.util.MergeUtilities;
|
||||
|
@ -700,17 +701,8 @@ class FunctionMerger extends AbstractFunctionMerger implements ListingMerger {
|
|||
f.setParentNamespace(ns);
|
||||
}
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Setting Function Namespace", e.getMessage());
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Setting Function Namespace", e.getMessage());
|
||||
}
|
||||
catch (CircularDependencyException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Setting Function Namespace", e.getMessage());
|
||||
catch (DuplicateNameException | InvalidInputException | CircularDependencyException e) {
|
||||
MergeManager.showBlockingError("Error Setting Function Namespace", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -762,17 +754,10 @@ class FunctionMerger extends AbstractFunctionMerger implements ListingMerger {
|
|||
listingMergeManager.resolveNamespace(origP, origF.getParentNamespace());
|
||||
resultF.setParentNamespace(ns);
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Setting Function Namespace", e.getMessage());
|
||||
}
|
||||
catch (InvalidInputException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Setting Function Namespace", e.getMessage());
|
||||
}
|
||||
catch (CircularDependencyException e) {
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(),
|
||||
"Error Setting Function Namespace", e.getMessage());
|
||||
catch (DuplicateNameException | InvalidInputException
|
||||
| CircularDependencyException e) {
|
||||
MergeManager.showBlockingError("Error Setting Function Namespace",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1453,8 +1438,7 @@ class FunctionMerger extends AbstractFunctionMerger implements ListingMerger {
|
|||
private void showOverlapException(final Address entryPt, Exception e) {
|
||||
String message = "Couldn't display body address set conflict for function at " +
|
||||
entryPt.toString(true) + ".\n " + e.getMessage();
|
||||
Msg.showError(this, mergeManager.getMergeTool().getToolFrame(), "Function Merge Error",
|
||||
message, e);
|
||||
MergeManager.showBlockingError("Function Merge Error", message, e);
|
||||
// Should this just put a message on errorBuf instead?
|
||||
}
|
||||
|
||||
|
@ -1738,7 +1722,7 @@ class FunctionMerger extends AbstractFunctionMerger implements ListingMerger {
|
|||
thunkChoice = choiceForFunctionConflict;
|
||||
break;
|
||||
default:
|
||||
Msg.showError(this, listingMergePanel, "Unrecognized Function Conflict Type",
|
||||
MergeManager.showBlockingError("Unrecognized Function Conflict Type",
|
||||
"Unrecognized indicator (" + functionConflictType +
|
||||
") for function conflict type to merge.");
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import javax.swing.SwingUtilities;
|
|||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import ghidra.app.merge.MergeManager;
|
||||
import ghidra.app.merge.tool.ListingMergePanel;
|
||||
import ghidra.app.merge.util.ConflictUtility;
|
||||
import ghidra.program.database.function.FunctionManagerDB;
|
||||
|
@ -249,14 +250,12 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
|
|||
// in these change sets.
|
||||
AddressSetView myChangedAddresses =
|
||||
listingMergeMgr.diffOriginalMy.getDifferences(new ProgramDiffFilter(diffType), monitor);
|
||||
AddressSetView latestChangedAddresses = listingMergeMgr.diffOriginalLatest.getDifferences(
|
||||
new ProgramDiffFilter(diffType), monitor);
|
||||
AddressSetView latestChangedAddresses = listingMergeMgr.diffOriginalLatest
|
||||
.getDifferences(new ProgramDiffFilter(diffType), monitor);
|
||||
|
||||
// Get a list of all deleted tags in My and Latest.
|
||||
Collection<? extends FunctionTag> myDeletedTags =
|
||||
getDeletedTags(myPgm, monitor);
|
||||
Collection<? extends FunctionTag> latestDeletedTags =
|
||||
getDeletedTags(latestPgm, monitor);
|
||||
Collection<? extends FunctionTag> myDeletedTags = getDeletedTags(myPgm, monitor);
|
||||
Collection<? extends FunctionTag> latestDeletedTags = getDeletedTags(latestPgm, monitor);
|
||||
|
||||
// Loop over all changed addresses in My and see if any added tags are in the
|
||||
// Latest delete list. If so, conflict panel!
|
||||
|
@ -421,7 +420,8 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
|
|||
String my = myTag == null ? "<tag deleted>" : myTag.getName();
|
||||
|
||||
conflictPanel.setRowHeader(new String[] { "Option", "Function Tags" });
|
||||
String text = "Function Tag conflict @ address :" + ConflictUtility.getAddressString(addr);
|
||||
String text =
|
||||
"Function Tag conflict @ address :" + ConflictUtility.getAddressString(addr);
|
||||
conflictPanel.setHeader(text);
|
||||
|
||||
conflictPanel.setRowHeader(getFunctionTagInfo(-1, null));
|
||||
|
@ -474,8 +474,8 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
|
|||
* @param monitor
|
||||
* @throws CancelledException
|
||||
*/
|
||||
private void mergeConflictingTag(Address addr, int chosenConflictOption,
|
||||
TaskMonitor monitor) throws CancelledException {
|
||||
private void mergeConflictingTag(Address addr, int chosenConflictOption, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
|
||||
int resolutionType = ProgramMergeFilter.MERGE;
|
||||
|
||||
|
@ -595,8 +595,8 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
|
|||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setupConflictsPanel(listingPanel, FunctionTagListingMerger.this.currentAddress, tagID,
|
||||
changeListener);
|
||||
setupConflictsPanel(listingPanel, FunctionTagListingMerger.this.currentAddress,
|
||||
tagID, changeListener);
|
||||
listingPanel.setBottomComponent(conflictPanel);
|
||||
}
|
||||
});
|
||||
|
@ -613,7 +613,7 @@ public class FunctionTagListingMerger extends AbstractListingMerger {
|
|||
});
|
||||
}
|
||||
catch (InterruptedException | InvocationTargetException e) {
|
||||
Msg.showError(this, null, "Merge Error", "Error displaying merge panel", e);
|
||||
MergeManager.showBlockingError("Merge Error", "Error displaying merge panel", e);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import javax.swing.event.ChangeEvent;
|
|||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import ghidra.app.merge.MergeConstants;
|
||||
import ghidra.app.merge.MergeManager;
|
||||
import ghidra.app.merge.tool.ListingMergePanel;
|
||||
import ghidra.app.merge.util.ConflictUtility;
|
||||
import ghidra.app.merge.util.MergeUtilities;
|
||||
|
@ -182,19 +183,19 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
totalChanges = 7;
|
||||
|
||||
if (mergeManager != null) {
|
||||
latestResolvedSymbols =
|
||||
(LongLongHashtable) mergeManager.getResolveInformation(MergeConstants.RESOLVED_LATEST_SYMBOLS);
|
||||
myResolvedSymbols =
|
||||
(LongLongHashtable) mergeManager.getResolveInformation(MergeConstants.RESOLVED_MY_SYMBOLS);
|
||||
origResolvedSymbols =
|
||||
(LongLongHashtable) mergeManager.getResolveInformation(MergeConstants.RESOLVED_ORIGINAL_SYMBOLS);
|
||||
latestResolvedSymbols = (LongLongHashtable) mergeManager
|
||||
.getResolveInformation(MergeConstants.RESOLVED_LATEST_SYMBOLS);
|
||||
myResolvedSymbols = (LongLongHashtable) mergeManager
|
||||
.getResolveInformation(MergeConstants.RESOLVED_MY_SYMBOLS);
|
||||
origResolvedSymbols = (LongLongHashtable) mergeManager
|
||||
.getResolveInformation(MergeConstants.RESOLVED_ORIGINAL_SYMBOLS);
|
||||
|
||||
pickedLatestCodeUnits =
|
||||
(AddressSetView) mergeManager.getResolveInformation(MergeConstants.PICKED_LATEST_CODE_UNITS);
|
||||
pickedMyCodeUnits =
|
||||
(AddressSetView) mergeManager.getResolveInformation(MergeConstants.PICKED_MY_CODE_UNITS);
|
||||
pickedOriginalCodeUnits =
|
||||
(AddressSetView) mergeManager.getResolveInformation(MergeConstants.PICKED_ORIGINAL_CODE_UNITS);
|
||||
pickedLatestCodeUnits = (AddressSetView) mergeManager
|
||||
.getResolveInformation(MergeConstants.PICKED_LATEST_CODE_UNITS);
|
||||
pickedMyCodeUnits = (AddressSetView) mergeManager
|
||||
.getResolveInformation(MergeConstants.PICKED_MY_CODE_UNITS);
|
||||
pickedOriginalCodeUnits = (AddressSetView) mergeManager
|
||||
.getResolveInformation(MergeConstants.PICKED_ORIGINAL_CODE_UNITS);
|
||||
}
|
||||
updateProgressMessage("Setting references where code units were merged...");
|
||||
autoMergeWhereCodeUnitsMerged(monitor);
|
||||
|
@ -363,8 +364,7 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
}
|
||||
|
||||
private void processOriginalRefs(Reference[] originalRefs) {
|
||||
for (int origIndex = 0; origIndex < originalRefs.length; origIndex++) {
|
||||
Reference originalRef = originalRefs[origIndex];
|
||||
for (Reference originalRef : originalRefs) {
|
||||
Reference myRef = DiffUtility.getReference(originalPgm, originalRef, myPgm);
|
||||
Reference latestRef = DiffUtility.getReference(originalPgm, originalRef, latestPgm);
|
||||
if (myRef == null) {
|
||||
|
@ -406,8 +406,7 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
|
||||
private void processMyRefsAdded(Reference[] myRefs) {
|
||||
// Check Adds which could result in an AddConflict or a type conflict.
|
||||
for (int myIndex = 0; myIndex < myRefs.length; myIndex++) {
|
||||
Reference myRef = myRefs[myIndex];
|
||||
for (Reference myRef : myRefs) {
|
||||
Reference originalRef = DiffUtility.getReference(myPgm, myRef, originalPgm);
|
||||
if (originalRef == null) {
|
||||
Reference latestRef = DiffUtility.getReference(myPgm, myRef, latestPgm);
|
||||
|
@ -432,7 +431,8 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
* @param operandIndex
|
||||
* @return
|
||||
*/
|
||||
private Reference getFallThroughReference(Program program, Address fromAddress, int operandIndex) {
|
||||
private Reference getFallThroughReference(Program program, Address fromAddress,
|
||||
int operandIndex) {
|
||||
Reference[] otherRefs =
|
||||
program.getReferenceManager().getReferencesFrom(fromAddress, operandIndex);
|
||||
for (Reference reference : otherRefs) {
|
||||
|
@ -450,7 +450,8 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
// If both refs changed from original then conflict.
|
||||
Reference origForLatest =
|
||||
DiffUtility.getReference(latestPgm, latestPrimary, originalPgm);
|
||||
if (origForLatest != null && diffOriginalLatest.equalRefs(origForLatest, latestPrimary)) {
|
||||
if (origForLatest != null &&
|
||||
diffOriginalLatest.equalRefs(origForLatest, latestPrimary)) {
|
||||
return;
|
||||
}
|
||||
Reference origForMy = DiffUtility.getReference(myPgm, myPrimary, originalPgm);
|
||||
|
@ -490,8 +491,8 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
private boolean hasRefTypeConflict(Reference[] latestRefs, Reference[] myRefs,
|
||||
Reference[] originalRefs) {
|
||||
if (originalRefs.length > 0) {
|
||||
return (compatibleRefs(originalRefs[0], latestRefs) && compatibleRefs(originalRefs[0],
|
||||
myRefs));
|
||||
return (compatibleRefs(originalRefs[0], latestRefs) &&
|
||||
compatibleRefs(originalRefs[0], myRefs));
|
||||
}
|
||||
else if (latestRefs.length > 0) {
|
||||
return (compatibleRefs(latestRefs[0], myRefs));
|
||||
|
@ -531,32 +532,32 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
private boolean compatibleRefs(Reference ref1, Reference[] refs) {
|
||||
Address toAddr = ref1.getToAddress();
|
||||
if (toAddr.isMemoryAddress()) {
|
||||
for (int i = 0; i < refs.length; i++) {
|
||||
if (!refs[i].getToAddress().isMemoryAddress()) {
|
||||
for (Reference ref : refs) {
|
||||
if (!ref.getToAddress().isMemoryAddress()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (toAddr.isExternalAddress()) {
|
||||
for (int i = 0; i < refs.length; i++) {
|
||||
if (!refs[i].getToAddress().isExternalAddress()) {
|
||||
for (Reference ref : refs) {
|
||||
if (!ref.getToAddress().isExternalAddress()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (toAddr.isRegisterAddress()) {
|
||||
for (int i = 0; i < refs.length; i++) {
|
||||
if (!refs[i].getToAddress().isRegisterAddress()) {
|
||||
for (Reference ref : refs) {
|
||||
if (!ref.getToAddress().isRegisterAddress()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (toAddr.isStackAddress()) {
|
||||
for (int i = 0; i < refs.length; i++) {
|
||||
if (!refs[i].getToAddress().isStackAddress()) {
|
||||
for (Reference ref : refs) {
|
||||
if (!ref.getToAddress().isStackAddress()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -703,8 +704,8 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
*/
|
||||
@Override
|
||||
public void mergeConflicts(ListingMergePanel listingPanel, Address addr,
|
||||
int chosenConflictOption, TaskMonitor monitor) throws CancelledException,
|
||||
MemoryAccessException {
|
||||
int chosenConflictOption, TaskMonitor monitor)
|
||||
throws CancelledException, MemoryAccessException {
|
||||
if (!hasConflict(addr)) {
|
||||
return;
|
||||
}
|
||||
|
@ -768,8 +769,7 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
currentOpIndex = opIndex;
|
||||
currentBackgroundSet = new AddressSet(addr, addr);
|
||||
currentConflictType = REMOVE_CONFLICT;
|
||||
for (Iterator<Reference> iter = removeList.iterator(); iter.hasNext();) {
|
||||
Reference removeRef = iter.next();
|
||||
for (Reference removeRef : removeList) {
|
||||
currentReference = removeRef;
|
||||
if (currentReference.getOperandIndex() == opIndex) {
|
||||
// If we have a reference choice then a "Use For All" has already occurred.
|
||||
|
@ -800,8 +800,7 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
currentOpIndex = opIndex;
|
||||
currentBackgroundSet = new AddressSet(addr, addr);
|
||||
currentConflictType = CHANGE_CONFLICT;
|
||||
for (Iterator<Reference> iter = changeList.iterator(); iter.hasNext();) {
|
||||
Reference changeRef = iter.next();
|
||||
for (Reference changeRef : changeList) {
|
||||
currentReference = changeRef;
|
||||
if (currentReference.getOperandIndex() == opIndex) {
|
||||
// If we have a reference choice then a "Use For All" has already occurred.
|
||||
|
@ -832,8 +831,7 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
currentOpIndex = opIndex;
|
||||
currentBackgroundSet = new AddressSet(addr, addr);
|
||||
currentConflictType = ADD_CONFLICT;
|
||||
for (Iterator<Reference> iter = addList.iterator(); iter.hasNext();) {
|
||||
Reference changeRef = iter.next();
|
||||
for (Reference changeRef : addList) {
|
||||
currentReference = changeRef;
|
||||
if (currentReference.getReferenceType().isFallthrough()) {
|
||||
continue; // Ignore fallthrough references.
|
||||
|
@ -957,7 +955,7 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
listingPanel.setBottomComponent(conflictPanel);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.showError(this, listingPanel, "Error Merging References",
|
||||
MergeManager.showBlockingError("Error Merging References",
|
||||
"Error Getting Conflict Panel", e);
|
||||
}
|
||||
}
|
||||
|
@ -1060,20 +1058,19 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
Reference[] myRefs = myRefMgr.getReferencesFrom(fromAddress, opIndex);
|
||||
panel.setTitle("Reference");
|
||||
String fromAddrStr = ConflictUtility.getAddressString(fromAddress);
|
||||
String text =
|
||||
" Conflicting reference types, " + getRefGroup(latestRefs[0]) + " & " +
|
||||
getRefGroup(myRefs[0]) + ", at '" + fromAddrStr + "' " +
|
||||
getOperandIndexString(opIndex) + ".";
|
||||
String text = " Conflicting reference types, " + getRefGroup(latestRefs[0]) + " & " +
|
||||
getRefGroup(myRefs[0]) + ", at '" + fromAddrStr + "' " +
|
||||
getOperandIndexString(opIndex) + ".";
|
||||
panel.setHeader(text);
|
||||
panel.setRowHeader(getReferenceInfo(null, null, null, null));
|
||||
String suffix = "' version";
|
||||
panel.addRadioButtonRow(
|
||||
getReferenceInfo(latestPgm, ((latestRefs.length == 1) ? latestRefs[0] : null),
|
||||
((latestRefs.length == 1) ? "Use '" : "Use all in '"), suffix), LATEST_BUTTON_NAME,
|
||||
KEEP_LATEST, listener);
|
||||
((latestRefs.length == 1) ? "Use '" : "Use all in '"), suffix),
|
||||
LATEST_BUTTON_NAME, KEEP_LATEST, listener);
|
||||
if (latestRefs.length > 1) {
|
||||
for (int i = 0; i < latestRefs.length; i++) {
|
||||
panel.addInfoRow(getReferenceInfo(latestPgm, latestRefs[i], "'", suffix));
|
||||
for (Reference latestRef : latestRefs) {
|
||||
panel.addInfoRow(getReferenceInfo(latestPgm, latestRef, "'", suffix));
|
||||
}
|
||||
}
|
||||
panel.addRadioButtonRow(
|
||||
|
@ -1081,12 +1078,12 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
((myRefs.length == 1) ? "Use '" : "Use all in '"), suffix),
|
||||
CHECKED_OUT_BUTTON_NAME, KEEP_MY, listener);
|
||||
if (myRefs.length > 1) {
|
||||
for (int i = 0; i < myRefs.length; i++) {
|
||||
panel.addInfoRow(getReferenceInfo(myPgm, myRefs[i], "'", suffix));
|
||||
for (Reference myRef : myRefs) {
|
||||
panel.addInfoRow(getReferenceInfo(myPgm, myRef, "'", suffix));
|
||||
}
|
||||
}
|
||||
panel.addInfoRow(getReferenceInfo(originalPgm, ((originalRefs.length > 0) ? originalRefs[0]
|
||||
: null), "'", suffix));
|
||||
panel.addInfoRow(getReferenceInfo(originalPgm,
|
||||
((originalRefs.length > 0) ? originalRefs[0] : null), "'", suffix));
|
||||
for (int i = 1; i < originalRefs.length; i++) {
|
||||
panel.addInfoRow(getReferenceInfo(originalPgm, originalRefs[i], "'", suffix));
|
||||
}
|
||||
|
@ -1109,13 +1106,11 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
}
|
||||
panel.setTitle("Reference");
|
||||
String fromAddrStr = ConflictUtility.getAddressString(ref.getFromAddress());
|
||||
String toAddrStr =
|
||||
ConflictUtility.colorString(ConflictUtility.ADDRESS_COLOR,
|
||||
DiffUtility.getUserToAddressString(resultPgm, ref.getToAddress()));
|
||||
String text =
|
||||
getRefGroup(ref) + " Reference from '" + fromAddrStr + "' " +
|
||||
getOperandIndexString(ref) + " to '" + toAddrStr +
|
||||
"' was removed in one version and changed in other.";
|
||||
String toAddrStr = ConflictUtility.colorString(ConflictUtility.ADDRESS_COLOR,
|
||||
DiffUtility.getUserToAddressString(resultPgm, ref.getToAddress()));
|
||||
String text = getRefGroup(ref) + " Reference from '" + fromAddrStr + "' " +
|
||||
getOperandIndexString(ref) + " to '" + toAddrStr +
|
||||
"' was removed in one version and changed in other.";
|
||||
panel.setHeader(text);
|
||||
panel.setRowHeader(getReferenceInfo(null, null, null, null));
|
||||
String latestPrefix = (latestRef == null) ? "Remove as in '" : "Change as in '";
|
||||
|
@ -1130,15 +1125,15 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
return panel;
|
||||
}
|
||||
|
||||
protected VerticalChoicesPanel getChangeConflictPanel(Reference myRef, ChangeListener listener) {
|
||||
protected VerticalChoicesPanel getChangeConflictPanel(Reference myRef,
|
||||
ChangeListener listener) {
|
||||
VerticalChoicesPanel panel = getVerticalConflictPanel();
|
||||
panel.setTitle("Reference");
|
||||
Address fromAddr = myRef.getFromAddress();
|
||||
int opIndex = myRef.getOperandIndex();
|
||||
String fromAddrStr = ConflictUtility.getAddressString(myRef.getFromAddress());
|
||||
String toAddrStr =
|
||||
ConflictUtility.colorString(ConflictUtility.ADDRESS_COLOR,
|
||||
DiffUtility.getUserToAddressString(resultPgm, myRef.getToAddress()));
|
||||
String toAddrStr = ConflictUtility.colorString(ConflictUtility.ADDRESS_COLOR,
|
||||
DiffUtility.getUserToAddressString(resultPgm, myRef.getToAddress()));
|
||||
Reference latestRef;
|
||||
Reference originalRef;
|
||||
if (myRef.isMemoryReference()) {
|
||||
|
@ -1153,15 +1148,13 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
}
|
||||
String text;
|
||||
if (myRef.isExternalReference()) {
|
||||
text =
|
||||
getRefGroup(myRef) + " Reference from '" + fromAddrStr + "' " +
|
||||
getOperandIndexString(myRef) + " was changed in both versions.";
|
||||
text = getRefGroup(myRef) + " Reference from '" + fromAddrStr + "' " +
|
||||
getOperandIndexString(myRef) + " was changed in both versions.";
|
||||
}
|
||||
else {
|
||||
text =
|
||||
getRefGroup(myRef) + " Reference from '" + fromAddrStr + "' " +
|
||||
getOperandIndexString(myRef) + " to '" + toAddrStr +
|
||||
"' was changed in both versions.";
|
||||
text = getRefGroup(myRef) + " Reference from '" + fromAddrStr + "' " +
|
||||
getOperandIndexString(myRef) + " to '" + toAddrStr +
|
||||
"' was changed in both versions.";
|
||||
}
|
||||
panel.setHeader(text);
|
||||
panel.setRowHeader(getReferenceInfo(null, null, null, null));
|
||||
|
@ -1195,9 +1188,8 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
}
|
||||
panel.setTitle("Reference");
|
||||
String fromAddrStr = ConflictUtility.getAddressString(myRef.getFromAddress());
|
||||
String text =
|
||||
getRefGroup(myRef) + " Reference from '" + fromAddrStr + "' " +
|
||||
getOperandIndexString(myRef) + " was added in both versions.";
|
||||
String text = getRefGroup(myRef) + " Reference from '" + fromAddrStr + "' " +
|
||||
getOperandIndexString(myRef) + " was added in both versions.";
|
||||
panel.setHeader(text);
|
||||
panel.setRowHeader(getReferenceInfo(null, null, null, null));
|
||||
String latestPrefix = "Use '";
|
||||
|
@ -1219,9 +1211,8 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
Reference myPrimary = myRefMgr.getPrimaryReferenceFrom(fromAddress, opIndex);
|
||||
panel.setTitle("Reference");
|
||||
String fromAddrStr = ConflictUtility.getAddressString(fromAddress);
|
||||
String text =
|
||||
" Conflicting primary references at '" + fromAddrStr + "' " +
|
||||
getOperandIndexString(opIndex) + ".";
|
||||
String text = " Conflicting primary references at '" + fromAddrStr + "' " +
|
||||
getOperandIndexString(opIndex) + ".";
|
||||
panel.setHeader(text);
|
||||
panel.setRowHeader(getReferenceInfo(null, null, null, null));
|
||||
String prefix = "Set '";
|
||||
|
@ -1485,7 +1476,8 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
return resultRef;
|
||||
}
|
||||
|
||||
private void resolvePrimaryConflict(Address fromAddress, int opIndex, int chosenConflictOption) {
|
||||
private void resolvePrimaryConflict(Address fromAddress, int opIndex,
|
||||
int chosenConflictOption) {
|
||||
if ((chosenConflictOption & KEEP_LATEST) != 0) {
|
||||
Reference latest = latestRefMgr.getPrimaryReferenceFrom(fromAddress, opIndex);
|
||||
Reference result = DiffUtility.getReference(latestPgm, latest, resultPgm);
|
||||
|
@ -1536,7 +1528,7 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
referenceChoice = choiceForConflictType;
|
||||
break;
|
||||
default:
|
||||
Msg.showError(this, listingMergePanel, "Unrecognized Reference Conflict Type",
|
||||
MergeManager.showBlockingError("Unrecognized Reference Conflict Type",
|
||||
"Unrecognized indicator (" + programMergeConflictType +
|
||||
") for reference conflict type to merge.");
|
||||
}
|
||||
|
@ -1552,8 +1544,7 @@ class ReferenceMerger extends AbstractListingMerger {
|
|||
}
|
||||
Symbol latestSymbol = latestPgm.getSymbolTable().getSymbol(latestSymbolID);
|
||||
if (latestSymbol != null) {
|
||||
Symbol resultSymbol =
|
||||
SimpleDiffUtility.getSymbol(latestSymbol, resultPgm);
|
||||
Symbol resultSymbol = SimpleDiffUtility.getSymbol(latestSymbol, resultPgm);
|
||||
if (resultSymbol != null) {
|
||||
return resultSymbol.getID();
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ public class DeleteAction extends DockingAction {
|
|||
"Are you sure you want to delete selected\n" +
|
||||
"data types and/or categories?\n\n" +
|
||||
"Note: Changes may trigger the removal of related\n" +
|
||||
"data types, components and defined data.)");
|
||||
"data types, components and defined data.");
|
||||
//@formatter:on
|
||||
if (choice != OptionDialog.OPTION_ONE) {
|
||||
return;
|
||||
|
|
|
@ -19,7 +19,6 @@ import static org.junit.Assert.*;
|
|||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JButton;
|
||||
|
@ -101,6 +100,10 @@ public abstract class AbstractMergeTest extends AbstractGhidraHeadedIntegrationT
|
|||
}
|
||||
|
||||
private void tryToPressCancel() {
|
||||
DockingWindowManager activeInstance = DockingWindowManager.getActiveInstance();
|
||||
if (activeInstance == null) {
|
||||
return;
|
||||
}
|
||||
Window window = DockingWindowManager.getActiveInstance().getActiveWindow();
|
||||
JButton cancel = findButtonByText(window, "Cancel");
|
||||
if (cancel == null) {
|
||||
|
@ -191,12 +194,11 @@ public abstract class AbstractMergeTest extends AbstractGhidraHeadedIntegrationT
|
|||
}
|
||||
ArrayList<String> list = tx.getOpenSubTransactions();
|
||||
StringBuffer tip = new StringBuffer();
|
||||
Iterator<String> iter = list.iterator();
|
||||
while (iter.hasNext()) {
|
||||
for (String element : list) {
|
||||
if (tip.length() != 0) {
|
||||
tip.append('\n');
|
||||
}
|
||||
tip.append(iter.next());
|
||||
tip.append(element);
|
||||
}
|
||||
Msg.error(this, prefix + "Test Case " + testName.getMethodName() +
|
||||
" : ERROR: Transactions still exist! " + tip.toString());
|
||||
|
|
|
@ -321,4 +321,8 @@ public abstract class AbstractDataTypeMergeTest extends AbstractMergeTest {
|
|||
chooseApply();
|
||||
}
|
||||
|
||||
void dismissUnresolvedDataTypesPopup() {
|
||||
pressButtonByName(waitForWindow("Unresolved Data Types and Components"), "OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -99,8 +99,7 @@ public class DataTypeMerge1Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyLatest(ProgramDB program) {
|
||||
// change the name
|
||||
Category c = program.getDataTypeManager()
|
||||
.getCategory(
|
||||
new CategoryPath("/Category1/Category2/Category5"));
|
||||
.getCategory(new CategoryPath("/Category1/Category2/Category5"));
|
||||
try {
|
||||
c.createCategory("AnotherCategory");
|
||||
}
|
||||
|
@ -261,8 +260,7 @@ public class DataTypeMerge1Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyLatest(ProgramDB program) {
|
||||
// change the name
|
||||
Category c = program.getDataTypeManager()
|
||||
.getCategory(
|
||||
new CategoryPath("/Category1/Category2/Category5"));
|
||||
.getCategory(new CategoryPath("/Category1/Category2/Category5"));
|
||||
try {
|
||||
c.createCategory("AnotherCategory");
|
||||
Structure dt = new StructureDataType("Test", 0);
|
||||
|
@ -315,8 +313,7 @@ public class DataTypeMerge1Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyLatest(ProgramDB program) {
|
||||
// change the name
|
||||
Category c = program.getDataTypeManager()
|
||||
.getCategory(
|
||||
new CategoryPath("/Category1/Category2/Category5"));
|
||||
.getCategory(new CategoryPath("/Category1/Category2/Category5"));
|
||||
try {
|
||||
c.createCategory("AnotherCategory");
|
||||
StructureDataType dt = new StructureDataType("Test", 0);
|
||||
|
@ -541,18 +538,32 @@ public class DataTypeMerge1Test extends AbstractDataTypeMergeTest {
|
|||
foo.insert(1, dt);
|
||||
}
|
||||
});
|
||||
executeMerge(DataTypeMergeManager.OPTION_MY);
|
||||
|
||||
executeMerge();
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
// CoolUnion should not have been added back in
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
DataType dt = dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
assertNull(dt);
|
||||
|
||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
DataTypeComponent[] dtcs = foo.getComponents();
|
||||
// components 1-97 should be default data types
|
||||
for (int i = 1; i < 97; i++) {
|
||||
assertEquals(DataType.DEFAULT, dtcs[i].getDataType());
|
||||
}
|
||||
assertNotNull(foo);
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/Foo\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Foo {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 -BAD- 96 \"Failed to apply 'CoolUnion'\"\n" +
|
||||
" 97 byte 1 \"\"\n" +
|
||||
" 98 word 2 \"\"\n" +
|
||||
" 100 Bar 6 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 106 Alignment: 1\n", foo.toString());
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -951,9 +962,8 @@ public class DataTypeMerge1Test extends AbstractDataTypeMergeTest {
|
|||
});
|
||||
executeMerge(DataTypeMergeManager.OPTION_MY);
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
Structure s = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
DataTypeComponent dtc = s.getComponent(2);
|
||||
assertEquals("My_Field_Three", dtc.getFieldName());
|
||||
assertEquals("my comments for Field 3", dtc.getComment());
|
||||
|
|
|
@ -99,10 +99,10 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
DataType cdt = dtm.getDataType(new CategoryPath("/Category1/Category2/Category4"),
|
||||
"CharStruct");
|
||||
Structure s = (Structure) dt;
|
||||
Array array = new ArrayDataType(cdt, 5, cdt.getLength());
|
||||
Array array = new ArrayDataType(cdt, 0, cdt.getLength());
|
||||
s.add(new ByteDataType());
|
||||
s.add(new WordDataType());
|
||||
s.add(array);
|
||||
s.add(new PointerDataType(array, dtm));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -116,8 +116,8 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
DataType cdt = dtm.getDataType(new CategoryPath("/Category1/Category2/Category4"),
|
||||
"CharStruct");
|
||||
Structure s = (Structure) dt;
|
||||
Array array = new ArrayDataType(cdt, 3, cdt.getLength());
|
||||
s.add(array);
|
||||
Array array = new ArrayDataType(cdt, 0, cdt.getLength());
|
||||
s.add(new PointerDataType(array, dtm));
|
||||
s.add(new ByteDataType());
|
||||
s.add(new WordDataType());
|
||||
}
|
||||
|
@ -132,7 +132,8 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
Structure s = (Structure) dt;
|
||||
assertEquals(7, s.getNumComponents());
|
||||
DataTypeComponent dtc = s.getComponent(4);
|
||||
assertTrue(dtc.getDataType() instanceof Array);
|
||||
System.out.println(dtc.getDataType());
|
||||
//assertTrue(dtc.getDataType() instanceof Array);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -366,7 +367,7 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
dt.setName("OtherIntStruct");
|
||||
Structure s = (Structure) dt;
|
||||
s.add(new ByteDataType());
|
||||
s.add(new WordDataType());;
|
||||
s.add(new WordDataType());
|
||||
}
|
||||
catch (DuplicateNameException e) {
|
||||
Assert.fail("Got Duplicate name exception!");
|
||||
|
@ -1018,10 +1019,9 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
Structure s1 = (Structure) dtm.getDataType(new CategoryPath("/Category1/Category2"),
|
||||
"Structure_1");
|
||||
"Structure_1");
|
||||
// create a TypeDef on Bar
|
||||
TypeDef td =
|
||||
new TypedefDataType(new CategoryPath("/MISC"), "MyBar_Typedef", bar);
|
||||
TypeDef td = new TypedefDataType(new CategoryPath("/MISC"), "MyBar_Typedef", bar);
|
||||
// create a Pointer to typedef on Bar
|
||||
Pointer p = PointerDataType.getPointer(foo, 4);// Foo *
|
||||
p = PointerDataType.getPointer(td, 4);// MyBar_Typedef *
|
||||
|
@ -1039,7 +1039,14 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
s1.add(bar);
|
||||
}
|
||||
});
|
||||
executeMerge(DataTypeMergeManager.OPTION_MY);// choose my Foo
|
||||
|
||||
executeMerge();
|
||||
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
// Bar should not have been added back in
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
|
@ -1047,32 +1054,50 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
assertNull(bar);
|
||||
Structure s1 =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2"), "Structure_1");
|
||||
DataTypeComponent[] dtcs = s1.getDefinedComponents();
|
||||
assertEquals(4, dtcs.length);
|
||||
assertEquals(20, s1.getLength());
|
||||
|
||||
dtcs = s1.getComponents();
|
||||
for (int i = 6; i < 10; i++) {
|
||||
assertEquals(DataType.DEFAULT, dtcs[i].getDataType());
|
||||
}
|
||||
assertNotNull(s1);
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/Structure_1\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Structure_1 {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 word 2 \"\"\n" +
|
||||
" 3 Foo 10 \"\"\n" +
|
||||
" 13 byte 1 \"\"\n" +
|
||||
" 14 -BAD- 6 \"Failed to apply 'Bar'\"\n" +
|
||||
"}\n" +
|
||||
"Length: 20 Alignment: 1\n", s1.toString());
|
||||
//@formatter:on
|
||||
|
||||
TypeDef td = (TypeDef) dtm.getDataType(new CategoryPath("/MISC"), "MyBar_Typedef");
|
||||
assertNull(td);
|
||||
|
||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
assertNotNull(foo);
|
||||
// Foo should not have MyBar_Typedef * * * * * * * *
|
||||
dtcs = foo.getDefinedComponents();
|
||||
assertEquals(3, dtcs.length);
|
||||
assertEquals(14, foo.getLength());
|
||||
dtcs = foo.getComponents();
|
||||
for (int i = 10; i < 13; i++) {
|
||||
assertEquals(DataType.DEFAULT, dtcs[i].getDataType());
|
||||
}
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/Foo\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Foo {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 byte 1 \"\"\n" +
|
||||
" 2 word 2 \"\"\n" +
|
||||
" 4 -BAD- 6 \"Failed to apply 'Bar'\"\n" +
|
||||
" 10 -BAD- 4 \"Failed to apply 'MyBar_Typedef * * * * * * * *'\"\n" +
|
||||
"}\n" +
|
||||
"Length: 14 Alignment: 1\n", foo.toString());
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddedFuncSig() throws Exception {
|
||||
|
||||
ParameterDefinitionImpl p1 =
|
||||
new ParameterDefinitionImpl("pw", WordDataType.dataType, "Comment1");
|
||||
ParameterDefinitionImpl p2 =
|
||||
new ParameterDefinitionImpl("pwp", new PointerDataType(WordDataType.dataType), null);
|
||||
ParameterDefinitionImpl p3 =
|
||||
new ParameterDefinitionImpl("pwa", new ArrayDataType(WordDataType.dataType, 1), null);
|
||||
|
||||
mtf.initialize("notepad2", new ProgramModifierListener() {
|
||||
|
||||
@Override
|
||||
|
@ -1081,6 +1106,10 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
// remove Bar from the data type manager
|
||||
dtm.remove(bar, TaskMonitor.DUMMY);
|
||||
DataType word = dtm.getDataType(new CategoryPath("/"), "word");
|
||||
// remove Bar and word from the data type manager
|
||||
dtm.remove(bar, TaskMonitor.DUMMY);
|
||||
dtm.remove(word, TaskMonitor.DUMMY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1101,6 +1130,7 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
new FunctionDefinitionDataType(func, false);
|
||||
functionDef.setReturnType(bar);
|
||||
functionDef.setCategoryPath(new CategoryPath("/MISC"));
|
||||
functionDef.setArguments(p1, p2, p3);
|
||||
dtm.addDataType(functionDef, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
@ -1109,13 +1139,29 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
}
|
||||
}
|
||||
});
|
||||
executeMerge(-1);
|
||||
executeMerge();
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
assertNull(dtm.getDataType(new CategoryPath("/MISC"), "Bar"));
|
||||
FunctionDefinition fd =
|
||||
(FunctionDefinition) dtm.getDataType(new CategoryPath("/MISC"), "entry");
|
||||
assertNotNull(fd);
|
||||
assertEquals(DataType.DEFAULT, fd.getReturnType());
|
||||
ParameterDefinition[] arguments = fd.getArguments();
|
||||
assertEquals(3, arguments.length);
|
||||
assertSameArgument(p1, arguments[0]);
|
||||
assertSameArgument(p2, arguments[1]);
|
||||
assertSameArgument(p3, arguments[2]);
|
||||
}
|
||||
|
||||
private void assertSameArgument(ParameterDefinition p1, ParameterDefinition p2) {
|
||||
assertTrue(p1.getDataType().isEquivalent(p2.getDataType()));
|
||||
assertEquals(p1.getName(), p2.getName());
|
||||
assertEquals(p1.getComment(), p2.getComment());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1190,7 +1236,14 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
vars[1].setDataType(p);
|
||||
}
|
||||
});
|
||||
executeMerge(DataTypeMergeManager.OPTION_MY);
|
||||
executeMerge();
|
||||
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
FunctionDefinition fd =
|
||||
(FunctionDefinition) dtm.getDataType(new CategoryPath("/MISC"), "MyFunctionDef");
|
||||
|
@ -1201,8 +1254,10 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
assertEquals(dll, fd.getReturnType());
|
||||
ParameterDefinition[] vars = fd.getArguments();
|
||||
assertEquals(DataType.DEFAULT, vars[0].getDataType());
|
||||
assertEquals("this is a comment", vars[0].getComment());
|
||||
assertEquals("Failed to apply 'Foo'; this is a comment", vars[0].getComment());
|
||||
assertEquals(DataType.DEFAULT, vars[1].getDataType());
|
||||
assertEquals("Failed to apply 'Foo *'", vars[1].getComment());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1234,7 +1289,15 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
vars[1].setDataType(p);
|
||||
}
|
||||
});
|
||||
executeMerge(DataTypeMergeManager.OPTION_MY);
|
||||
|
||||
executeMerge();
|
||||
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
FunctionDefinition fd =
|
||||
(FunctionDefinition) dtm.getDataType(new CategoryPath("/MISC"), "MyFunctionDef");
|
||||
|
@ -1245,8 +1308,9 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
assertEquals(dll, fd.getReturnType());
|
||||
ParameterDefinition[] vars = fd.getArguments();
|
||||
assertEquals(DataType.DEFAULT, vars[0].getDataType());
|
||||
assertEquals("this is a comment", vars[0].getComment());
|
||||
assertEquals("Failed to apply 'Foo'; this is a comment", vars[0].getComment());
|
||||
assertEquals(DataType.DEFAULT, vars[1].getDataType());
|
||||
assertEquals("Failed to apply 'Foo *'", vars[1].getComment());
|
||||
assertFalse(fd.hasVarArgs());
|
||||
assertFalse(fd.hasNoReturn());
|
||||
}
|
||||
|
@ -1366,9 +1430,8 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
FunctionDefinition fd =
|
||||
new FunctionDefinitionDataType(new CategoryPath("/MISC"), "printf");
|
||||
fd.setReturnType(new WordDataType());
|
||||
fd.setArguments(
|
||||
new ParameterDefinition[] { new ParameterDefinitionImpl("format",
|
||||
new Pointer32DataType(new StringDataType()), null) });
|
||||
fd.setArguments(new ParameterDefinition[] { new ParameterDefinitionImpl("format",
|
||||
new Pointer32DataType(new StringDataType()), null) });
|
||||
fd.setVarArgs(false);
|
||||
dtm.addDataType(fd, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
}
|
||||
|
@ -1379,9 +1442,8 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
FunctionDefinition fd =
|
||||
new FunctionDefinitionDataType(new CategoryPath("/MISC"), "printf");
|
||||
fd.setReturnType(new WordDataType());
|
||||
fd.setArguments(
|
||||
new ParameterDefinition[] { new ParameterDefinitionImpl("format",
|
||||
new Pointer32DataType(new StringDataType()), null) });
|
||||
fd.setArguments(new ParameterDefinition[] { new ParameterDefinitionImpl("format",
|
||||
new Pointer32DataType(new StringDataType()), null) });
|
||||
fd.setVarArgs(true);
|
||||
dtm.addDataType(fd, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
}
|
||||
|
@ -1424,9 +1486,8 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
new FunctionDefinitionDataType(new CategoryPath("/MISC"), "exit");
|
||||
fd.setReturnType(VoidDataType.dataType);
|
||||
fd.setNoReturn(false);
|
||||
fd.setArguments(
|
||||
new ParameterDefinition[] { new ParameterDefinitionImpl("rc",
|
||||
IntegerDataType.dataType, null) });
|
||||
fd.setArguments(new ParameterDefinition[] {
|
||||
new ParameterDefinitionImpl("rc", IntegerDataType.dataType, null) });
|
||||
dtm.addDataType(fd, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
}
|
||||
|
||||
|
@ -1437,9 +1498,8 @@ public class DataTypeMerge2Test extends AbstractDataTypeMergeTest {
|
|||
new FunctionDefinitionDataType(new CategoryPath("/MISC"), "exit");
|
||||
fd.setReturnType(VoidDataType.dataType);
|
||||
fd.setNoReturn(true);
|
||||
fd.setArguments(
|
||||
new ParameterDefinition[] { new ParameterDefinitionImpl("rc",
|
||||
IntegerDataType.dataType, null) });
|
||||
fd.setArguments(new ParameterDefinition[] {
|
||||
new ParameterDefinitionImpl("rc", IntegerDataType.dataType, null) });
|
||||
dtm.addDataType(fd, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -70,22 +70,39 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
Category c = dtm.getCategory(new CategoryPath("/Category1/Category2"));
|
||||
Union union = (Union) c.getDataType("CoolUnion");
|
||||
assertNotNull(union);
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/CoolUnion\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Union CoolUnion {\n" +
|
||||
" 0 qword 8 \"\"\n" +
|
||||
" 0 word 2 \"\"\n" +
|
||||
" 0 undefined * * * * * 4 \"\"\n" +
|
||||
" 0 -BAD- 96 \"Type 'DLL_Table' was deleted\"\n" +
|
||||
" 0 -BAD- 4 \"Type 'DLL_Table *' was deleted\"\n" +
|
||||
"}\n" +
|
||||
"Length: 96 Alignment: 1\n", union.toString());
|
||||
//@formatter:on;
|
||||
|
||||
// DLL_Table should have a Word data type as the last component
|
||||
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
||||
DataTypeComponent dtc = s.getComponent(s.getNumComponents() - 1);
|
||||
assertTrue(dtc.getDataType().isEquivalent(new WordDataType()));
|
||||
|
||||
// CoolUnion should not have DLL_Table components
|
||||
DataTypeComponent[] dtcs = union.getComponents();
|
||||
assertEquals(3, dtcs.length);
|
||||
DataType dt = dtcs[2].getDataType();
|
||||
assertTrue(dt instanceof Pointer);
|
||||
|
||||
// DLL_Table should have Word added to it
|
||||
dtcs = s.getDefinedComponents();
|
||||
assertEquals(9, dtcs.length);
|
||||
assertTrue(dtcs[8].getDataType().isEquivalent(new WordDataType()));
|
||||
assertNotNull(s);
|
||||
//@formatter:off
|
||||
assertEquals("/DLL_Table\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure DLL_Table {\n" +
|
||||
" 0 string 13 COMDLG32 \"\"\n" +
|
||||
" 13 string 12 SHELL32 \"\"\n" +
|
||||
" 25 string 11 MSVCRT \"\"\n" +
|
||||
" 36 string 13 ADVAPI32 \"\"\n" +
|
||||
" 49 string 13 KERNEL32 \"\"\n" +
|
||||
" 62 string 10 GDI32 \"\"\n" +
|
||||
" 72 string 11 USER32 \"\"\n" +
|
||||
" 83 string 13 WINSPOOL32 \"\"\n" +
|
||||
" 96 word 2 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 98 Alignment: 1\n", s.toString());
|
||||
//@formatter:on;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -97,7 +114,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
Structure s = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
||||
dtm.remove(s, TaskMonitor.DUMMY);
|
||||
// 2 components should get removed from CoolUnion
|
||||
// 2 components should be bad in CoolUnion
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -127,23 +144,33 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
// MY CoolUnion
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
|
||||
Category c = dtm.getCategory(new CategoryPath("/Category1/Category2"));
|
||||
Union union = (Union) c.getDataType("CoolUnion");
|
||||
assertNotNull(union);
|
||||
|
||||
// DLL_Table should not exist
|
||||
assertNull(dtm.getDataType(CategoryPath.ROOT, "DLL_Table"));
|
||||
|
||||
// CoolUnion should not have DLL_Table components but should have Float
|
||||
DataTypeComponent[] dtcs = union.getComponents();
|
||||
assertEquals(4, dtcs.length);
|
||||
DataType dt = dtcs[3].getDataType();
|
||||
assertTrue(dt.isEquivalent(new FloatDataType()));
|
||||
assertEquals("my comments", dtcs[3].getComment());
|
||||
assertEquals("Float_Field", dtcs[3].getFieldName());
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/CoolUnion\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Union CoolUnion {\n" +
|
||||
" 0 qword 8 \"\"\n" +
|
||||
" 0 word 2 \"\"\n" +
|
||||
" 0 undefined * * * * * 4 \"\"\n" +
|
||||
" 0 -BAD- 98 \"Failed to apply 'DLL_Table'\"\n" +
|
||||
" 0 -BAD- 4 \"Failed to apply 'DLL_Table *'\"\n" +
|
||||
" 0 float 4 Float_Field \"my comments\"\n" +
|
||||
"}\n" +
|
||||
"Length: 98 Alignment: 1\n", union.toString());
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -231,7 +258,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
executeMerge();
|
||||
|
||||
close(waitForWindow("Structure Update Failed")); // expected dependency error on Foo
|
||||
pressButtonByName(waitForWindow("Structure Update Failed"), "OK"); // expected dependency error on Foo
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
|
@ -257,7 +284,8 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
// original CoolUnion becomes CoolUnion.conflict.
|
||||
assertEquals("float", fooComps[5].getDataType().getDisplayName());
|
||||
assertTrue(fooComps[4].getDataType() instanceof BadDataType);
|
||||
assertTrue(fooComps[4].getComment().startsWith("Couldn't add CoolUnion here."));
|
||||
assertEquals("Failed to apply 'CoolUnion', Data type CoolUnion has Foo within it.",
|
||||
fooComps[4].getComment());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -295,7 +323,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);// MY Foo
|
||||
|
||||
close(waitForWindow("Structure Update Failed")); // expected dependency error on Foo
|
||||
pressButtonByName(waitForWindow("Structure Update Failed"), "OK"); // expected dependency error on Foo
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
|
@ -305,23 +333,40 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
Union coolUnion =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
DataTypeComponent[] coolUnionComps = coolUnion.getComponents();
|
||||
assertEquals(6, coolUnionComps.length);
|
||||
|
||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
DataTypeComponent[] fooComps = foo.getComponents();
|
||||
assertEquals(6, fooComps.length);
|
||||
assertNotNull(coolUnion);
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/CoolUnion\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Union CoolUnion {\n" +
|
||||
" 0 qword 8 \"\"\n" +
|
||||
" 0 word 2 \"\"\n" +
|
||||
" 0 undefined * * * * * 4 \"\"\n" +
|
||||
" 0 DLL_Table 96 \"\"\n" +
|
||||
" 0 DLL_Table *32 4 \"\"\n" +
|
||||
" 0 Foo 110 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 110 Alignment: 1\n", coolUnion.toString());
|
||||
//@formatter:on
|
||||
|
||||
// Foo should not contain CoolUnion because CoolUnion already
|
||||
// contains Foo (from Latest)
|
||||
assertEquals("Foo", coolUnionComps[5].getDataType().getDisplayName());
|
||||
|
||||
// Foo.conflict should contain CoolUnion.conflict because CoolUnion already
|
||||
// contains Foo (from Latest), so Foo (From My) becomes Foo.conflict and its
|
||||
// original CoolUnion becomes CoolUnion.conflict.
|
||||
assertEquals("float", fooComps[5].getDataType().getDisplayName());
|
||||
assertTrue(fooComps[4].getDataType() instanceof BadDataType);
|
||||
assertTrue(fooComps[4].getComment().startsWith("Couldn't add CoolUnion here."));
|
||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
assertNotNull(foo);
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/Foo\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Foo {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 byte 1 \"\"\n" +
|
||||
" 2 word 2 \"\"\n" +
|
||||
" 4 Bar 6 \"\"\n" +
|
||||
" 10 -BAD- 96 \"Failed to apply 'CoolUnion', Data type CoolUnion has Foo within it.\"\n" +
|
||||
" 106 float 4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 110 Alignment: 1\n", foo.toString());
|
||||
//@formatter:on
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -409,7 +454,7 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);// My Bar
|
||||
|
||||
close(waitForWindow("Structure Update Failed")); // expected dependency error on Bar
|
||||
pressButtonByName(waitForWindow("Structure Update Failed"), "OK"); // expected dependency error on Bar
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
|
@ -419,21 +464,33 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
Union coolUnion =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
assertNotNull(coolUnion);
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/CoolUnion\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Union CoolUnion {\n" +
|
||||
" 0 qword 8 \"\"\n" +
|
||||
" 0 word 2 \"\"\n" +
|
||||
" 0 undefined * * * * * 4 \"\"\n" +
|
||||
" 0 DLL_Table 96 \"\"\n" +
|
||||
" 0 DLL_Table *32 4 \"\"\n" +
|
||||
" 0 Bar 102 My_field_name \"My comments\"\n" +
|
||||
"}\n" +
|
||||
"Length: 102 Alignment: 1\n", coolUnion.toString());
|
||||
//@formatter:on
|
||||
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
assertNotNull(bar);
|
||||
|
||||
DataTypeComponent[] coolUnionComps = coolUnion.getComponents();
|
||||
assertEquals(6, coolUnionComps.length);
|
||||
DataTypeComponent[] barComps = bar.getDefinedComponents();
|
||||
assertEquals(3, barComps.length);
|
||||
|
||||
assertEquals(bar, coolUnionComps[5].getDataType());
|
||||
assertEquals("My_field_name", coolUnionComps[5].getFieldName());
|
||||
assertEquals("My comments", coolUnionComps[5].getComment());
|
||||
|
||||
assertTrue(barComps[2].getDataType() instanceof BadDataType);
|
||||
assertTrue(barComps[2].getComment().startsWith("Couldn't add CoolUnion here."));
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/Bar\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Bar {\n" +
|
||||
" 0 word 2 \"\"\n" +
|
||||
" 2 Structure_1 *32 4 \"\"\n" +
|
||||
" 6 -BAD- 96 \"Failed to apply 'CoolUnion', Data type CoolUnion has Bar within it.\"\n" +
|
||||
"}\n" +
|
||||
"Length: 102 Alignment: 1\n", bar.toString());
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -587,18 +644,25 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
chooseOption(DataTypeMergeManager.OPTION_LATEST);// delele Structure_1 (choose Structure_1 from MY)
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
|
||||
// Bar should contain undefined to replace Structure_1
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
assertEquals(7, bar.getLength());
|
||||
DataTypeComponent[] dtcs = bar.getComponents();
|
||||
assertEquals(6, dtcs.length);
|
||||
for (int i = 1; i < 5; i++) {
|
||||
assertEquals(DataType.DEFAULT, dtcs[i].getDataType());
|
||||
}
|
||||
assertNotNull(bar);
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/Bar\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Bar {\n" +
|
||||
" 0 word 2 \"\"\n" +
|
||||
" 2 -BAD- 4 \"Failed to apply 'Structure_1 *'\"\n" +
|
||||
" 6 byte 1 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 7 Alignment: 1\n", bar.toString());
|
||||
//@formatter:on;
|
||||
|
||||
// Structure_1 should have been deleted
|
||||
Structure s1 =
|
||||
|
@ -606,9 +670,20 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
assertNull(s1);
|
||||
|
||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
dtcs = foo.getDefinedComponents();
|
||||
assertEquals(5, dtcs.length);
|
||||
assertEquals(bar, dtcs[3].getDataType());
|
||||
assertNotNull(foo);
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/Foo\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Foo {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 byte 1 \"\"\n" +
|
||||
" 2 word 2 \"\"\n" +
|
||||
" 4 Bar 7 \"\"\n" +
|
||||
" 11 float 4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 15 Alignment: 1\n", foo.toString());
|
||||
//@formatter:on;
|
||||
|
||||
checkConflictCount(0);
|
||||
}
|
||||
|
||||
|
@ -644,14 +719,14 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
Structure fs =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category5"),
|
||||
"FloatStruct");
|
||||
Structure s = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "ArrayStruct");
|
||||
Structure a = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "ArrayStruct");
|
||||
Structure ms = (Structure) dtm.getDataType(new CategoryPath("/Category1/Category2"),
|
||||
"MyStruct");
|
||||
s.add(new FloatDataType());
|
||||
a.add(new FloatDataType());
|
||||
|
||||
Structure mys1 = new StructureDataType(
|
||||
new CategoryPath("/Category1/Category2/Category5"), "my_s1", 0);
|
||||
mys1.add(s);
|
||||
mys1.add(a);
|
||||
|
||||
mys1 = (Structure) dtm.addDataType(mys1, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
// edit FloatStruct
|
||||
|
@ -673,12 +748,15 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
// conflict on FloatStruct (2)
|
||||
chooseOption(DataTypeMergeManager.OPTION_LATEST);// delete FloatStruct
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
|
||||
assertNull(
|
||||
dtm.getDataType(new CategoryPath("/Category1/Category2/Category5"), "FloatStruct"));
|
||||
|
||||
waitForCompletion();
|
||||
Structure fs = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category5"), "FloatStruct");
|
||||
assertNull(fs);
|
||||
|
@ -686,16 +764,33 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
// MyStruct should have a FloatDataType and a Word
|
||||
Structure ms =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2"), "MyStruct");
|
||||
DataTypeComponent[] dtcs = ms.getDefinedComponents();
|
||||
assertEquals(4, dtcs.length);
|
||||
|
||||
assertTrue(dtcs[2].getDataType().isEquivalent(new FloatDataType()));
|
||||
assertTrue(dtcs[3].getDataType().isEquivalent(new WordDataType()));
|
||||
assertNotNull(ms);
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/MyStruct\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure MyStruct {\n" +
|
||||
" 0 -BAD- 120 \"Failed to apply 'FloatStruct[10]'\"\n" +
|
||||
" 120 IntStruct[3] 45 \"\"\n" +
|
||||
" 165 CharStruct * * * 4 \"\"\n" +
|
||||
" 169 float 4 \"\"\n" +
|
||||
" 173 word 2 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 175 Alignment: 1\n", ms.toString());
|
||||
//@formatter:on;
|
||||
|
||||
// ArrayStruct should have 3 components
|
||||
Structure a = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "ArrayStruct");
|
||||
dtcs = a.getDefinedComponents();
|
||||
assertEquals(3, dtcs.length);
|
||||
assertNotNull(a);
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/ArrayStruct\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure ArrayStruct {\n" +
|
||||
" 0 IntStruct * *[10] 40 \"\"\n" +
|
||||
" 40 IntStruct[3] 45 \"\"\n" +
|
||||
" 85 undefined * * * * * 4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 89 Alignment: 1\n", a.toString());
|
||||
//@formatter:on;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -728,6 +823,8 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
try {
|
||||
s1.insertBitFieldAt(3, 2, 6, td, 2, "bf1", "my bf1");
|
||||
s1.insertBitFieldAt(3, 2, 4, td, 2, "bf2", "my bf2");
|
||||
|
||||
// foo grows but does alter size of existing component in s1
|
||||
foo.add(new FloatDataType());
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
@ -739,45 +836,46 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
// bitfield silently transitions to int since typedef BF was removed
|
||||
|
||||
executeMerge(true);
|
||||
executeMerge();
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
|
||||
Structure s1 =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2"), "Structure_1");
|
||||
assertNotNull(s1);
|
||||
DataTypeComponent[] dtcs = s1.getComponents();
|
||||
assertEquals(7, dtcs.length);
|
||||
|
||||
assertEquals(4, dtcs[3].getOffset()); // base on original 2-byte length 1st byte remains undefined
|
||||
assertEquals("bf1", dtcs[3].getFieldName());
|
||||
assertEquals("my bf1", dtcs[3].getComment());
|
||||
|
||||
DataType dt = dtcs[3].getDataType();
|
||||
assertTrue(dt instanceof BitFieldDataType);
|
||||
BitFieldDataType bfDt = (BitFieldDataType) dt;
|
||||
assertTrue(bfDt.getBaseDataType() instanceof IntegerDataType);
|
||||
assertEquals(2, bfDt.getDeclaredBitSize());
|
||||
assertEquals(6, bfDt.getBitOffset());
|
||||
|
||||
assertEquals(4, dtcs[4].getOffset()); // base on original 2-byte length 1st byte remains undefined
|
||||
assertEquals("bf2", dtcs[4].getFieldName());
|
||||
assertEquals("my bf2", dtcs[4].getComment());
|
||||
|
||||
dt = dtcs[4].getDataType();
|
||||
assertTrue(dt instanceof BitFieldDataType);
|
||||
bfDt = (BitFieldDataType) dt;
|
||||
assertTrue(bfDt.getBaseDataType() instanceof IntegerDataType);
|
||||
assertEquals(2, bfDt.getDeclaredBitSize());
|
||||
assertEquals(4, bfDt.getBitOffset());
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/Structure_1\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Structure_1 {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 word 2 \"\"\n" +
|
||||
" 4 int:2(6) 1 bf1 \"Failed to apply 'BF'; my bf1\"\n" +
|
||||
" 4 int:2(4) 1 bf2 \"Failed to apply 'BF'; my bf2\"\n" +
|
||||
" 5 Foo 10 \"\"\n" +
|
||||
" 15 byte 1 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 16 Alignment: 1\n", s1.toString());
|
||||
//@formatter:on
|
||||
|
||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
// Structure_1 should contain MY Foo
|
||||
assertEquals(foo, dtcs[5].getDataType());
|
||||
assertNotNull(foo);
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/Foo\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Foo {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 byte 1 \"\"\n" +
|
||||
" 2 word 2 \"\"\n" +
|
||||
" 4 Bar 6 \"\"\n" +
|
||||
" 10 float 4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 14 Alignment: 1\n", foo.toString());
|
||||
//@formatter:on
|
||||
|
||||
dtcs = foo.getComponents();
|
||||
assertEquals(5, dtcs.length);
|
||||
assertTrue(dtcs[4].getDataType().isEquivalent(new FloatDataType()));
|
||||
checkConflictCount(0);
|
||||
}
|
||||
|
||||
|
@ -1215,6 +1313,8 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);// MY CoolUnion
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
|
@ -1228,16 +1328,31 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
Union union =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "AnotherUnion");
|
||||
assertNotNull(union);
|
||||
|
||||
DataTypeComponent[] dtcs = union.getComponents();
|
||||
assertEquals(1, dtcs.length);
|
||||
assertTrue(dtcs[0].getDataType().isEquivalent(new ByteDataType()));
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/AnotherUnion\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Union AnotherUnion {\n" +
|
||||
" 0 -BAD- 98 \"Failed to apply 'DLL_Table'\"\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 98 Alignment: 1\n", union.toString());
|
||||
//@formatter:on;
|
||||
|
||||
union = (Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
dtcs = union.getComponents();
|
||||
assertEquals(4, dtcs.length);
|
||||
assertEquals("my comments", dtcs[3].getComment());
|
||||
assertEquals("Float_Field", dtcs[3].getFieldName());
|
||||
assertNotNull(union);
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/CoolUnion\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Union CoolUnion {\n" +
|
||||
" 0 qword 8 \"\"\n" +
|
||||
" 0 word 2 \"\"\n" +
|
||||
" 0 undefined * * * * * 4 \"\"\n" +
|
||||
" 0 -BAD- 98 \"Failed to apply 'DLL_Table'\"\n" +
|
||||
" 0 -BAD- 4 \"Failed to apply 'DLL_Table *'\"\n" +
|
||||
" 0 float 4 Float_Field \"my comments\"\n" +
|
||||
"}\n" +
|
||||
"Length: 98 Alignment: 1\n", union.toString());
|
||||
//@formatter:on;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1363,6 +1478,8 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);// MY CoolUnion
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
|
@ -1371,19 +1488,25 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
Union union =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
assertNotNull(union);
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/CoolUnion\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Union CoolUnion {\n" +
|
||||
" 0 qword 8 \"\"\n" +
|
||||
" 0 word 2 \"\"\n" +
|
||||
" 0 undefined * * * * * 4 \"\"\n" +
|
||||
" 0 -BAD- 98 \"Failed to apply 'DLL_Table'\"\n" +
|
||||
" 0 -BAD- 4 \"Failed to apply 'DLL_Table *'\"\n" +
|
||||
" 0 float 4 Float_Field \"my comments\"\n" +
|
||||
" 0 MyEnum 1 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 98 Alignment: 1\n", union.toString());
|
||||
//@formatter:on;
|
||||
|
||||
// DLL_Table should be null
|
||||
Structure dll = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
||||
assertNull(dll);
|
||||
|
||||
DataTypeComponent[] dtcs = union.getComponents();
|
||||
assertEquals(5, dtcs.length);
|
||||
|
||||
Enum enumm = (Enum) dtm.getDataType(new CategoryPath("/Category1"), "MyEnum");
|
||||
assertNotNull(enumm);
|
||||
assertEquals(enumm, dtcs[4].getDataType());
|
||||
assertTrue(dtcs[3].getDataType().isEquivalent(new FloatDataType()));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1515,24 +1638,49 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
|
||||
Enum enumm = (Enum) dtm.getDataType(new CategoryPath("/Category1"), "MyEnum");
|
||||
assertNotNull(enumm);
|
||||
|
||||
TypeDef td = (TypeDef) dtm.getDataType(new CategoryPath("/Category1"), "TD_MyEnum");
|
||||
assertNotNull(td);
|
||||
|
||||
// CoolUnion should not be null
|
||||
Union union =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
assertNotNull(union);
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/CoolUnion\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Union CoolUnion {\n" +
|
||||
" 0 qword 8 \"\"\n" +
|
||||
" 0 word 2 \"\"\n" +
|
||||
" 0 undefined * * * * * 4 \"\"\n" +
|
||||
" 0 DLL_Table 96 \"\"\n" +
|
||||
" 0 DLL_Table *32 4 \"\"\n" +
|
||||
" 0 float 4 Float_Field \"my comments\"\n" +
|
||||
" 0 TD_MyEnum 1 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 96 Alignment: 1\n", union.toString());
|
||||
//@formatter:on;
|
||||
|
||||
// DLL_Table should not be null
|
||||
Structure dll = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
||||
assertNotNull(dll);
|
||||
|
||||
DataTypeComponent[] dtcs = union.getComponents();
|
||||
assertEquals(7, dtcs.length);
|
||||
|
||||
Enum enumm = (Enum) dtm.getDataType(new CategoryPath("/Category1"), "MyEnum");
|
||||
assertNotNull(enumm);
|
||||
TypeDef td = (TypeDef) dtm.getDataType(new CategoryPath("/Category1"), "TD_MyEnum");
|
||||
assertNotNull(td);
|
||||
assertEquals(td, dtcs[6].getDataType());
|
||||
assertEquals(dll, dtcs[3].getDataType());
|
||||
//@formatter:off
|
||||
assertEquals("/DLL_Table\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure DLL_Table {\n" +
|
||||
" 0 string 13 COMDLG32 \"\"\n" +
|
||||
" 13 string 12 SHELL32 \"\"\n" +
|
||||
" 25 string 11 MSVCRT \"\"\n" +
|
||||
" 36 string 13 ADVAPI32 \"\"\n" +
|
||||
" 49 string 13 KERNEL32 \"\"\n" +
|
||||
" 62 string 10 GDI32 \"\"\n" +
|
||||
" 72 string 11 USER32 \"\"\n" +
|
||||
" 83 string 13 WINSPOOL32 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 96 Alignment: 1\n", dll.toString());
|
||||
//@formatter:on;
|
||||
|
||||
checkConflictCount(0);
|
||||
}
|
||||
|
@ -1778,6 +1926,8 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);// MY bitfields w/ enum
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
|
@ -1790,8 +1940,8 @@ public class DataTypeMerge3Test extends AbstractDataTypeMergeTest {
|
|||
"pack(disabled)\n" +
|
||||
"Union CoolUnion {\n" +
|
||||
" 0 qword 8 \"\"\n" +
|
||||
" 0 byte:4(4) 1 BF1 \"my bf1\"\n" +
|
||||
" 0 byte:2(6) 1 BF2 \"my bf2\"\n" +
|
||||
" 0 byte:4(4) 1 BF1 \"Failed to apply 'XYZ'; my bf1\"\n" +
|
||||
" 0 byte:2(6) 1 BF2 \"Failed to apply 'XYZ'; my bf2\"\n" +
|
||||
" 0 word 2 \"\"\n" +
|
||||
" 0 undefined * * * * * 4 \"\"\n" +
|
||||
" 0 DLL_Table 96 \"\"\n" +
|
||||
|
|
|
@ -19,6 +19,8 @@ import static org.junit.Assert.*;
|
|||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.JDialog;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -380,17 +382,15 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
Structure s = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "ArrayStruct");
|
||||
Structure intstruct =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"MyIntStruct");
|
||||
Structure intstruct = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "MyIntStruct");
|
||||
DataTypeComponent[] idtcs = intstruct.getDefinedComponents();
|
||||
assertEquals(7, idtcs.length);
|
||||
DataType dt = idtcs[6].getDataType();
|
||||
assertTrue(dt instanceof Pointer);
|
||||
|
||||
Structure mystruct =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"my_struct");
|
||||
Structure mystruct = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "my_struct");
|
||||
assertNotNull(mystruct);
|
||||
|
||||
assertEquals(mystruct, ((Pointer) dt).getDataType());
|
||||
|
@ -446,48 +446,56 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
}
|
||||
});
|
||||
executeMerge();
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
Thread.sleep(250);
|
||||
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);// Choose my Foo
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
|
||||
// Foo should exist
|
||||
Structure fs = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
assertNotNull(fs);
|
||||
DataTypeComponent[] dtcs = fs.getDefinedComponents();
|
||||
assertEquals(3, dtcs.length);
|
||||
DataTypeComponent dtc = fs.getComponent(2);
|
||||
DataType dt = dtc.getDataType();
|
||||
assertTrue(dt instanceof Pointer);
|
||||
|
||||
// Foo should have a pointer to Foo
|
||||
assertEquals(fs, ((Pointer) dt).getDataType());
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/Foo\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Foo {\n" +
|
||||
" 0 qword 8 \"\"\n" +
|
||||
" 8 Bar 6 \"\"\n" +
|
||||
" 14 Foo *32 4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 18 Alignment: 1\n", fs.toString());
|
||||
//@formatter:on
|
||||
|
||||
// my_struct should have a Foo and Byte
|
||||
Structure ms =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"my_struct");
|
||||
Structure ms = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "my_struct");
|
||||
assertNotNull(ms);
|
||||
|
||||
assertEquals(2, ms.getDefinedComponents().length);
|
||||
dtc = ms.getComponent(0);
|
||||
assertEquals(fs, dtc.getDataType());
|
||||
dtc = ms.getComponent(1);
|
||||
assertTrue(new ByteDataType().isEquivalent(dtc.getDataType()));
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/Category3/my_struct\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure my_struct {\n" +
|
||||
" 0 Foo 18 \"\"\n" +
|
||||
" 18 byte 1 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 19 Alignment: 1\n", ms.toString());
|
||||
//@formatter:on
|
||||
|
||||
// Structure1 should exist as modified by Latest. (My didn't change it.)
|
||||
Structure s1 =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2"), "Structure_1");
|
||||
assertNotNull(s1);
|
||||
DataTypeComponent[] dtcs1 = s1.getDefinedComponents();
|
||||
assertEquals(3, dtcs1.length);
|
||||
DataType dt0 = dtcs1[0].getDataType();
|
||||
DataType dt1 = dtcs1[1].getDataType();
|
||||
DataType dt2 = dtcs1[2].getDataType();
|
||||
assertTrue(dt0 instanceof ByteDataType);
|
||||
assertTrue(dt1 instanceof WordDataType);
|
||||
assertTrue(dt2 instanceof ByteDataType);
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/Structure_1\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Structure_1 {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 word 2 \"\"\n" +
|
||||
" 3 -BAD- 10 \"Type 'Foo' was deleted\"\n" +
|
||||
" 13 byte 1 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 14 Alignment: 1\n", s1.toString());
|
||||
//@formatter:on
|
||||
|
||||
// should be no .conflict data types
|
||||
ArrayList<DataType> list = new ArrayList<DataType>();
|
||||
|
@ -527,56 +535,65 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
});
|
||||
|
||||
executeMerge();
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
|
||||
chooseOption(DataTypeMergeManager.OPTION_LATEST);// Bar gets a Foo
|
||||
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);// Foo keeps its Bar, which creates Foo.conflict.
|
||||
|
||||
close(waitForWindow("Structure Update Failed")); // expected dependency error on Bar (2 occurances of Bar use)
|
||||
pressButtonByName(waitForWindow("Structure Update Failed"), "OK"); // expected dependency error on Bar (2 occurances of Bar use)
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
|
||||
// should be two .conflict data types
|
||||
checkConflictCount(0);
|
||||
|
||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
|
||||
assertNotNull(foo);
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/Foo\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Foo {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 byte 1 \"\"\n" +
|
||||
" 2 word 2 \"\"\n" +
|
||||
" 4 -BAD- 6 \"Failed to apply 'Bar', Data type Bar has Foo within it.\"\n" +
|
||||
" 10 qword 8 \"\"\n" +
|
||||
" 18 -BAD- 6 \"Failed to apply 'Bar', Data type Bar has Foo within it.\"\n" +
|
||||
" 24 Foo *32 4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 28 Alignment: 1\n", foo.toString());
|
||||
//@formatter:on
|
||||
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
assertNotNull(bar);
|
||||
|
||||
DataTypeComponent[] barComps = bar.getDefinedComponents();
|
||||
assertEquals(3, barComps.length);
|
||||
|
||||
assertEquals(foo, barComps[2].getDataType());
|
||||
|
||||
DataTypeComponent[] fooComps = foo.getComponents();
|
||||
assertEquals(7, fooComps.length);
|
||||
assertEquals("byte", fooComps[0].getDataType().getDisplayName());
|
||||
assertEquals("byte", fooComps[1].getDataType().getDisplayName());
|
||||
assertEquals("word", fooComps[2].getDataType().getDisplayName());
|
||||
assertTrue(fooComps[3].getDataType() instanceof BadDataType);
|
||||
String comment3 = fooComps[3].getComment();
|
||||
assertTrue(comment3.startsWith("Couldn't add Bar here."));
|
||||
assertEquals("qword", fooComps[4].getDataType().getDisplayName());
|
||||
assertTrue(fooComps[5].getDataType() instanceof BadDataType);
|
||||
String comment5 = fooComps[5].getComment();
|
||||
assertTrue(comment5.startsWith("Couldn't add Bar here."));
|
||||
assertEquals("Foo *", fooComps[6].getDataType().getDisplayName());
|
||||
|
||||
DataTypeComponent[] dtcs = foo.getDefinedComponents();
|
||||
// Update should fail for Foo
|
||||
for (DataTypeComponent dtc : dtcs) {
|
||||
if (dtc.getDataType() == bar) {
|
||||
Assert.fail("Bar should not have been added to Foo!");
|
||||
}
|
||||
}
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/Bar\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Bar {\n" +
|
||||
" 0 word 2 \"\"\n" +
|
||||
" 2 Structure_1 *32 4 \"\"\n" +
|
||||
" 6 Foo 28 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 34 Alignment: 1\n", bar.toString());
|
||||
//@formatter:on
|
||||
|
||||
// Structure_1 should have a Foo component
|
||||
Structure s1 =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2"), "Structure_1");
|
||||
DataType dt = s1.getComponent(2).getDataType();
|
||||
assertEquals(foo, dt);
|
||||
assertNotNull(s1);
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/Structure_1\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Structure_1 {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 word 2 \"\"\n" +
|
||||
" 3 Foo 10 \"\"\n" +
|
||||
" 13 byte 1 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 14 Alignment: 1\n", s1.toString());
|
||||
//@formatter:on
|
||||
|
||||
// FooTypedef should have Foo as its base type
|
||||
TypeDef td = (TypeDef) dtm.getDataType(new CategoryPath("/MISC"), "FooTypedef");
|
||||
|
@ -658,6 +675,8 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
// new data types from MY should go in as .conflicts
|
||||
|
@ -846,6 +865,8 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);// choose Foo from MY
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
// new data types from MY should go in as .conflicts
|
||||
|
@ -853,22 +874,66 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
Structure bs = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
assertNull(bs);
|
||||
|
||||
Structure fs = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
assertNotNull(fs);
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/Foo\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Foo {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 byte 1 \"\"\n" +
|
||||
" 2 word 2 \"\"\n" +
|
||||
" 4 -BAD- 6 \"Failed to apply 'Bar'\"\n" +
|
||||
" 10 S1.conflict 5 \"\"\n" +
|
||||
" 15 S2.conflict 12 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 27 Alignment: 1\n", fs.toString());
|
||||
//@formatter:on
|
||||
|
||||
// Foo should have undefined bytes where Bar was
|
||||
DataTypeComponent[] dtcs = fs.getDefinedComponents();
|
||||
assertEquals(5, dtcs.length);
|
||||
Structure s1 = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "S1.conflict");
|
||||
assertEquals(s1, dtcs[3].getDataType());
|
||||
Structure s2 = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "S2.conflict");
|
||||
assertEquals(s2, dtcs[4].getDataType());
|
||||
assertNotNull(s1);
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/S1.conflict\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure S1.conflict {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 byte *32 4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 5 Alignment: 1\n", s1.toString());
|
||||
//@formatter:on
|
||||
|
||||
Structure s2 = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "S2.conflict");
|
||||
assertNotNull(s2);
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/S2.conflict\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure S2.conflict {\n" +
|
||||
" 0 Foo *32 4 \"\"\n" +
|
||||
" 4 qword 8 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 12 Alignment: 1\n", s2.toString());
|
||||
//@formatter:on
|
||||
|
||||
// Structure_1 should contain Foo from MY
|
||||
Structure struct_1 =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2"), "Structure_1");
|
||||
dtcs = struct_1.getDefinedComponents();
|
||||
assertNotNull(struct_1);
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/Structure_1\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Structure_1 {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 word 2 \"\"\n" +
|
||||
" 3 Foo 10 \"\"\n" +
|
||||
" 13 byte 1 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 14 Alignment: 1\n", struct_1.toString());
|
||||
//@formatter:on
|
||||
|
||||
// Structure_1 should contain Foo from MY although its component will not reflect
|
||||
// change in Foo size.
|
||||
assertTrue(struct_1.getDefinedComponents()[2].getDataType() == fs);
|
||||
|
||||
assertEquals(fs, dtcs[2].getDataType());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1156,6 +1221,14 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
p = PointerDataType.getPointer(p, 4);// MyArray_Typedef * * * * * * * *
|
||||
// add pointer to Foo
|
||||
foo.add(p);
|
||||
|
||||
foo.add(new ArrayDataType(p, 0, 0, dtm));
|
||||
|
||||
array = new ArrayDataType(bar, 0, 0, dtm);
|
||||
foo.add(array);
|
||||
|
||||
foo.add(new PointerDataType(array, dtm));
|
||||
|
||||
}
|
||||
});
|
||||
executeMerge();
|
||||
|
@ -1202,7 +1275,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
ArrayList<DataType> list = new ArrayList<DataType>();
|
||||
dtm.findDataTypes("MyArray_Typedef*", list, false, null);
|
||||
assertEquals(9, list.size());
|
||||
assertEquals(10, list.size());
|
||||
|
||||
assertNotNull(dtm.getDataType(new CategoryPath("/MISC"), "Bar[6][7][8][9][10][11]"));
|
||||
|
||||
|
@ -1264,6 +1337,13 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
p = PointerDataType.getPointer(p, 4);// MyArray_Typedef * * * * * * * *
|
||||
// add pointer to Foo
|
||||
foo.add(p);
|
||||
|
||||
foo.add(new ArrayDataType(p, 0, 0, dtm));
|
||||
|
||||
array = new ArrayDataType(bar, 0, 0, dtm);
|
||||
foo.add(array);
|
||||
|
||||
foo.add(new PointerDataType(array, dtm));
|
||||
}
|
||||
});
|
||||
executeMerge();
|
||||
|
@ -1282,6 +1362,14 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
assertNotNull(bar);
|
||||
|
||||
assertEquals("/MISC/Foo\n" + "pack(disabled)\n" + "Structure Foo {\n" +
|
||||
" 0 byte 1 \"\"\n" + " 1 byte 1 \"\"\n" +
|
||||
" 2 word 2 \"\"\n" + " 4 Bar 6 \"\"\n" +
|
||||
" 14 MyArray_Typedef *32 *32 *32 *32 *32 *32 *32 *32 4 \"\"\n" +
|
||||
" 18 MyArray_Typedef *32 *32 *32 *32 *32 *32 *32 *32[0] 0 \"\"\n" +
|
||||
" 18 Bar[0] 0 \"\"\n" + " 18 Bar[0] * 4 \"\"\n" + "}\n" +
|
||||
"Length: 22 Alignment: 1\n" + "", foo.toString());
|
||||
|
||||
// Bar should NOT have Foo * * * * * *
|
||||
DataTypeComponent[] dtcs = bar.getDefinedComponents();
|
||||
assertEquals(2, dtcs.length);
|
||||
|
@ -1289,7 +1377,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
//Foo should have MyArray_Typedef * * * * * * * *
|
||||
dtcs = foo.getDefinedComponents();
|
||||
assertEquals(5, dtcs.length);
|
||||
assertEquals(8, dtcs.length);
|
||||
DataType dt = dtcs[4].getDataType();
|
||||
TypeDef td = (TypeDef) dtm.getDataType(new CategoryPath("/MISC"), "MyArray_Typedef");
|
||||
assertNotNull(td);
|
||||
|
@ -1352,6 +1440,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
p = PointerDataType.getPointer(p, 4);// MyArray_Typedef * * * * * * * *
|
||||
// add pointer to Bar
|
||||
bar.add(p);
|
||||
|
||||
}
|
||||
});
|
||||
executeMerge();
|
||||
|
@ -1384,6 +1473,103 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
checkConflictCount(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeletedBaseTypeDef4() throws Exception {
|
||||
|
||||
mtf.initialize("notepad2", new ProgramModifierListener() {
|
||||
@Override
|
||||
public void modifyLatest(ProgramDB program) {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
// remove Bar from the data type manager
|
||||
dtm.remove(bar, TaskMonitor.DUMMY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyPrivate(ProgramDB program) {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
|
||||
// edit Bar to create conflict because Latest deleted it
|
||||
Pointer p = PointerDataType.getPointer(foo, 4);// Foo *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * * *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * * * * * *
|
||||
bar.add(p);
|
||||
|
||||
// create a multi-dimension array on Bar
|
||||
Array array = new ArrayDataType(bar, 11, bar.getLength());
|
||||
array = new ArrayDataType(array, 10, array.getLength());
|
||||
array = new ArrayDataType(array, 9, array.getLength());
|
||||
array = new ArrayDataType(array, 8, array.getLength());
|
||||
array = new ArrayDataType(array, 7, array.getLength());
|
||||
array = new ArrayDataType(array, 6, array.getLength());
|
||||
|
||||
// create a TypeDef on the array
|
||||
TypeDef td =
|
||||
new TypedefDataType(new CategoryPath("/MISC"), "MyArray_Typedef", array);
|
||||
// create a Pointer to typedef on MyArray_Typedef
|
||||
p = PointerDataType.getPointer(td, 4);// MyArray_Typedef *
|
||||
p = PointerDataType.getPointer(p, 4);// MyArray_Typedef * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyArray_Typedef * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyArray_Typedef * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyArray_Typedef * * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyArray_Typedef * * * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyArray_Typedef * * * * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyArray_Typedef * * * * * * * *
|
||||
// add pointer to Foo
|
||||
foo.add(p);
|
||||
|
||||
foo.add(new ArrayDataType(p, 0, 0, dtm));
|
||||
|
||||
array = new ArrayDataType(bar, 0, 0, dtm);
|
||||
foo.add(array);
|
||||
|
||||
foo.add(new PointerDataType(array, dtm));
|
||||
|
||||
}
|
||||
});
|
||||
executeMerge();
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
|
||||
// Conflict on Bar
|
||||
chooseOption(DataTypeMergeManager.OPTION_LATEST);// choose Bar deleted
|
||||
|
||||
// Conflict on Foo
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);// choose My Foo - Bar removal will cause problems
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
assertNull(bar);
|
||||
|
||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
assertNotNull(foo);
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/Foo\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Foo {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 byte 1 \"\"\n" +
|
||||
" 2 word 2 \"\"\n" +
|
||||
" 4 -BAD- 10 \"Failed to apply 'Bar'\"\n" +
|
||||
" 14 -BAD- 4 \"Failed to apply 'MyArray_Typedef * * * * * * * *'\"\n" +
|
||||
" 18 -BAD- 0 \"Failed to apply 'MyArray_Typedef * * * * * * * *[0]'\"\n" +
|
||||
" 18 -BAD- 0 \"Failed to apply 'Bar[0]'\"\n" +
|
||||
" 18 -BAD- 4 \"Failed to apply 'Bar[0] *'\"\n" +
|
||||
"}\n" +
|
||||
"Length: 22 Alignment: 1\n", foo.toString());
|
||||
//@formatter:on
|
||||
|
||||
// should be no .conflict data types
|
||||
checkConflictCount(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeletedBasePointerDT() throws Exception {
|
||||
|
||||
|
@ -1412,8 +1598,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
bar.add(p);
|
||||
|
||||
// create a TypeDef on Bar
|
||||
TypeDef td =
|
||||
new TypedefDataType(new CategoryPath("/MISC"), "MyBar_Typedef", bar);
|
||||
TypeDef td = new TypedefDataType(new CategoryPath("/MISC"), "MyBar_Typedef", bar);
|
||||
// create a Pointer to typedef on Bar
|
||||
p = PointerDataType.getPointer(td, 4);// MyBar_Typedef *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * *
|
||||
|
@ -1504,8 +1689,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
bar.add(p);
|
||||
|
||||
// create a TypeDef on Bar
|
||||
TypeDef td =
|
||||
new TypedefDataType(new CategoryPath("/MISC"), "MyBar_Typedef", bar);
|
||||
TypeDef td = new TypedefDataType(new CategoryPath("/MISC"), "MyBar_Typedef", bar);
|
||||
// create a Pointer to typedef on Bar
|
||||
p = PointerDataType.getPointer(td, 4);// MyBar_Typedef *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * *
|
||||
|
@ -1528,9 +1712,25 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
// Conflict on Foo
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);// choose Foo MY
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
assertNotNull(foo);
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/Foo\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Foo {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 byte 1 \"\"\n" +
|
||||
" 2 word 2 \"\"\n" +
|
||||
" 4 -BAD- 10 \"Failed to apply 'Bar'\"\n" +
|
||||
" 14 -BAD- 4 \"Failed to apply 'MyBar_Typedef * * * * * * * *'\"\n" +
|
||||
"}\n" +
|
||||
"Length: 18 Alignment: 1\n", foo.toString());
|
||||
//@formatter:on
|
||||
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
assertNull(bar);
|
||||
|
||||
|
@ -1538,14 +1738,6 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
TypeDef td = (TypeDef) dtm.getDataType(new CategoryPath("/MISC"), "MyBar_Typedef");
|
||||
assertNull(td);
|
||||
|
||||
DataTypeComponent[] dtcs = foo.getDefinedComponents();
|
||||
assertEquals(3, dtcs.length);
|
||||
dtcs = foo.getComponents();
|
||||
|
||||
// pointer gets converted to default
|
||||
for (int i = 4; i < dtcs.length; i++) {
|
||||
assertEquals(DataType.DEFAULT, dtcs[i].getDataType());
|
||||
}
|
||||
ArrayList<DataType> list = new ArrayList<DataType>();
|
||||
dtm.findDataTypes("MyBar_Typedef*", list, false, null);
|
||||
assertEquals(0, list.size());
|
||||
|
@ -1583,8 +1775,7 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
bar.add(p);
|
||||
|
||||
// create a TypeDef on Bar
|
||||
TypeDef td =
|
||||
new TypedefDataType(new CategoryPath("/MISC"), "MyBar_Typedef", bar);
|
||||
TypeDef td = new TypedefDataType(new CategoryPath("/MISC"), "MyBar_Typedef", bar);
|
||||
// create a Pointer to typedef on Bar
|
||||
p = PointerDataType.getPointer(td, 4);// MyBar_Typedef *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * *
|
||||
|
@ -1656,30 +1847,29 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
Structure bar = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Bar");
|
||||
|
||||
// edit Bar to create conflict because Latest deleted it
|
||||
Pointer p = PointerDataType.getPointer(foo, 4);// Foo *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * * *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * * * * * *
|
||||
bar.add(p);// This causes Bar to increase by 4 bytes
|
||||
// and Foo contains Bar at the end so it also increases by 4.
|
||||
// edit Bar to create conflict because Latest deleted it
|
||||
Pointer p = PointerDataType.getPointer(foo, 4);// Foo *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * * *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// Foo * * * * * *
|
||||
bar.add(p);// This causes Bar to increase by 4 bytes
|
||||
// and Foo contains Bar at the end so it also increases by 4.
|
||||
|
||||
// create a TypeDef on Bar
|
||||
TypeDef td =
|
||||
new TypedefDataType(new CategoryPath("/MISC"), "MyBar_Typedef", bar);
|
||||
// create a Pointer to typedef on Bar
|
||||
p = PointerDataType.getPointer(td, 4);// MyBar_Typedef *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * * * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * * * * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * * * * * * * *
|
||||
// add pointer to Foo
|
||||
foo.add(p);
|
||||
// create a TypeDef on Bar
|
||||
TypeDef td = new TypedefDataType(new CategoryPath("/MISC"), "MyBar_Typedef", bar);
|
||||
// create a Pointer to typedef on Bar
|
||||
p = PointerDataType.getPointer(td, 4);// MyBar_Typedef *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * * * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * * * * * * *
|
||||
p = PointerDataType.getPointer(p, 4);// MyBar_Typedef * * * * * * * *
|
||||
// add pointer to Foo
|
||||
foo.add(p);
|
||||
}
|
||||
});
|
||||
executeMerge();
|
||||
|
@ -1691,6 +1881,8 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
// Conflict on Foo
|
||||
chooseOption(DataTypeMergeManager.OPTION_MY);// choose Foo MY
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
// Bar should have been removed
|
||||
|
@ -1698,20 +1890,23 @@ public class DataTypeMerge4Test extends AbstractDataTypeMergeTest {
|
|||
assertNull(bar);
|
||||
|
||||
Structure foo = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
DataTypeComponent[] dtcs = foo.getDefinedComponents();
|
||||
assertEquals(3, dtcs.length);
|
||||
assertEquals("Structure Foo was the wrong size.", 18, foo.getLength());
|
||||
assertNotNull(foo);
|
||||
//@formatter:off
|
||||
assertEquals("/MISC/Foo\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Foo {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 byte 1 \"\"\n" +
|
||||
" 2 word 2 \"\"\n" +
|
||||
" 4 -BAD- 10 \"Failed to apply 'Bar'\"\n" +
|
||||
" 14 -BAD- 4 \"Failed to apply 'MyBar_Typedef * * * * * * * *'\"\n" +
|
||||
"}\n" +
|
||||
"Length: 18 Alignment: 1\n", foo.toString());
|
||||
//@formatter:on
|
||||
|
||||
// MyBar_Typedef should not exist since the option to delete Bar was chosen
|
||||
assertNull(dtm.getDataType(new CategoryPath("/MISC"), "MyBar_Typedef"));
|
||||
|
||||
dtcs = foo.getComponents();
|
||||
|
||||
// pointer gets converted to default
|
||||
for (int i = 4; i < dtcs.length; i++) {
|
||||
assertEquals(DataType.DEFAULT, dtcs[i].getDataType());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -342,8 +342,7 @@ public class DataTypeMerge5Test extends AbstractDataTypeMergeTest {
|
|||
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||
|
||||
// edit FavoriteColors
|
||||
Enum enumm =
|
||||
(Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
Enum enumm = (Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
enumm.remove("Red");
|
||||
enumm.remove("Black");
|
||||
enumm.add("Crimson", 6);
|
||||
|
@ -466,8 +465,7 @@ public class DataTypeMerge5Test extends AbstractDataTypeMergeTest {
|
|||
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||
|
||||
// delete FavoriteColors
|
||||
Enum enumm =
|
||||
(Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
Enum enumm = (Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
dtm.remove(enumm, TaskMonitor.DUMMY);
|
||||
}
|
||||
|
||||
|
@ -587,8 +585,7 @@ public class DataTypeMerge5Test extends AbstractDataTypeMergeTest {
|
|||
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||
|
||||
// delete FavoriteColors
|
||||
Enum enumm =
|
||||
(Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
Enum enumm = (Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
dtm.remove(enumm, TaskMonitor.DUMMY);
|
||||
}
|
||||
|
||||
|
@ -655,24 +652,47 @@ public class DataTypeMerge5Test extends AbstractDataTypeMergeTest {
|
|||
Union union =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
assertNotNull(union);
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/CoolUnion\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Union CoolUnion {\n" +
|
||||
" 0 qword 8 \"\"\n" +
|
||||
" 0 word 2 \"\"\n" +
|
||||
" 0 undefined * * * * * 4 \"\"\n" +
|
||||
" 0 DLL_Table 96 \"\"\n" +
|
||||
" 0 DLL_Table *32 4 \"\"\n" +
|
||||
" 0 float 4 Float_Field \"my comments\"\n" +
|
||||
" 0 -BAD- 4 typedef_field_name_TD_MyEnumPointer \"Type 'TD_MyEnumPointer' was deleted; a typedef\"\n" +
|
||||
"}\n" +
|
||||
"Length: 96 Alignment: 1\n", union.toString());
|
||||
//@formatter:on
|
||||
|
||||
// DLL_Table should not be null
|
||||
Structure dll = (Structure) dtm.getDataType(CategoryPath.ROOT, "DLL_Table");
|
||||
assertNotNull(dll);
|
||||
//@formatter:off
|
||||
assertEquals("/DLL_Table\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure DLL_Table {\n" +
|
||||
" 0 string 13 COMDLG32 \"\"\n" +
|
||||
" 13 string 12 SHELL32 \"\"\n" +
|
||||
" 25 string 11 MSVCRT \"\"\n" +
|
||||
" 36 string 13 ADVAPI32 \"\"\n" +
|
||||
" 49 string 13 KERNEL32 \"\"\n" +
|
||||
" 62 string 10 GDI32 \"\"\n" +
|
||||
" 72 string 11 USER32 \"\"\n" +
|
||||
" 83 string 13 WINSPOOL32 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 96 Alignment: 1\n", dll.toString());
|
||||
//@formatter:on
|
||||
|
||||
// Typedef should not have been created because we chose to
|
||||
// delete FavoriteColors (deleted in LATEST)
|
||||
Enum enumm = (Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
assertNull(enumm);
|
||||
|
||||
DataTypeComponent[] dtcs = union.getComponents();
|
||||
assertEquals(6, dtcs.length);
|
||||
assertEquals("Float_Field", dtcs[5].getFieldName());
|
||||
assertEquals("my comments", dtcs[5].getComment());
|
||||
|
||||
TypeDef td = (TypeDef) dtm.getDataType(new CategoryPath("/Category1"), "TD_MyEnumPointer");
|
||||
assertNull(td);
|
||||
assertEquals(dll, dtcs[3].getDataType());
|
||||
|
||||
ArrayList<DataType> list = new ArrayList<DataType>();
|
||||
dtm.findDataTypes("FavoriteColors*", list, false, null);
|
||||
|
@ -696,8 +716,7 @@ public class DataTypeMerge5Test extends AbstractDataTypeMergeTest {
|
|||
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||
|
||||
// edit FavoriteColors
|
||||
Enum enumm =
|
||||
(Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
Enum enumm = (Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
enumm.remove("Red");
|
||||
enumm.remove("Black");
|
||||
enumm.add("Crimson", 6);
|
||||
|
@ -821,8 +840,7 @@ public class DataTypeMerge5Test extends AbstractDataTypeMergeTest {
|
|||
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||
|
||||
// edit FavoriteColors
|
||||
Enum enumm =
|
||||
(Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
Enum enumm = (Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
enumm.remove("Red");
|
||||
enumm.remove("Black");
|
||||
enumm.add("Crimson", 6);
|
||||
|
@ -956,8 +974,7 @@ public class DataTypeMerge5Test extends AbstractDataTypeMergeTest {
|
|||
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||
|
||||
// edit FavoriteColors
|
||||
Enum enumm =
|
||||
(Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
Enum enumm = (Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
enumm.remove("Red");
|
||||
enumm.remove("Black");
|
||||
enumm.add("Crimson", 6);
|
||||
|
@ -1224,8 +1241,7 @@ public class DataTypeMerge5Test extends AbstractDataTypeMergeTest {
|
|||
|
||||
// must specify datatype manager when constructing to allow for settings to be made
|
||||
Pointer p = dtm.getPointer(CharDataType.dataType);
|
||||
TypeDef td =
|
||||
new TypedefDataType(new CategoryPath("/MISC"), "PtrTypeDef", p, dtm);
|
||||
TypeDef td = new TypedefDataType(new CategoryPath("/MISC"), "PtrTypeDef", p, dtm);
|
||||
|
||||
// NOTE: these are not viable settings but are intended to exercise all of them
|
||||
Settings settings = td.getDefaultSettings();
|
||||
|
@ -1246,8 +1262,7 @@ public class DataTypeMerge5Test extends AbstractDataTypeMergeTest {
|
|||
TypeDef td = (TypeDef) dtm.getDataType(new CategoryPath("/MISC"), "PtrTypeDef");
|
||||
|
||||
Settings settings = td.getDefaultSettings();
|
||||
PointerTypeSettingsDefinition.DEF.setType(settings,
|
||||
PointerType.RELATIVE);
|
||||
PointerTypeSettingsDefinition.DEF.setType(settings, PointerType.RELATIVE);
|
||||
AddressSpaceSettingsDefinition.DEF.clear(settings);
|
||||
OffsetMaskSettingsDefinition.DEF.clear(settings);
|
||||
OffsetShiftSettingsDefinition.DEF.setValue(settings, 3);
|
||||
|
@ -1328,8 +1343,7 @@ public class DataTypeMerge5Test extends AbstractDataTypeMergeTest {
|
|||
td.setName("Bob_Ptr_Td");
|
||||
|
||||
Settings settings = td.getDefaultSettings();
|
||||
PointerTypeSettingsDefinition.DEF.setType(settings,
|
||||
PointerType.RELATIVE);
|
||||
PointerTypeSettingsDefinition.DEF.setType(settings, PointerType.RELATIVE);
|
||||
|
||||
Structure st = (Structure) dtm.getDataType(new CategoryPath("/MISC"), "Foo");
|
||||
st.setName("Bob");
|
||||
|
@ -1375,9 +1389,8 @@ public class DataTypeMerge5Test extends AbstractDataTypeMergeTest {
|
|||
assertEquals("Bill", dt.getName());
|
||||
|
||||
Settings settings = td.getDefaultSettings();
|
||||
assertEquals(
|
||||
"Expected pointer-typedef type: relative",
|
||||
PointerType.RELATIVE, PointerTypeSettingsDefinition.DEF.getType(settings));
|
||||
assertEquals("Expected pointer-typedef type: relative", PointerType.RELATIVE,
|
||||
PointerTypeSettingsDefinition.DEF.getType(settings));
|
||||
assertFalse(
|
||||
"Unexpected setting: " +
|
||||
ComponentOffsetSettingsDefinition.DEF.getAttributeSpecification(settings),
|
||||
|
@ -1416,8 +1429,7 @@ public class DataTypeMerge5Test extends AbstractDataTypeMergeTest {
|
|||
td.setName("Bob_Ptr_Td");
|
||||
|
||||
Settings settings = td.getDefaultSettings();
|
||||
PointerTypeSettingsDefinition.DEF.setType(settings,
|
||||
PointerType.RELATIVE);
|
||||
PointerTypeSettingsDefinition.DEF.setType(settings, PointerType.RELATIVE);
|
||||
}
|
||||
catch (InvalidNameException | DuplicateNameException e) {
|
||||
failWithException("unexpected", e);
|
||||
|
@ -1447,9 +1459,8 @@ public class DataTypeMerge5Test extends AbstractDataTypeMergeTest {
|
|||
assertEquals("Bill", dt.getName());
|
||||
|
||||
Settings settings = td.getDefaultSettings();
|
||||
assertEquals(
|
||||
"Expected pointer-typedef type: relative",
|
||||
PointerType.RELATIVE, PointerTypeSettingsDefinition.DEF.getType(settings));
|
||||
assertEquals("Expected pointer-typedef type: relative", PointerType.RELATIVE,
|
||||
PointerTypeSettingsDefinition.DEF.getType(settings));
|
||||
assertFalse(
|
||||
"Unexpected setting: " +
|
||||
ComponentOffsetSettingsDefinition.DEF.getAttributeSpecification(settings),
|
||||
|
@ -1474,8 +1485,7 @@ public class DataTypeMerge5Test extends AbstractDataTypeMergeTest {
|
|||
dtm.remove(dt, TaskMonitor.DUMMY);
|
||||
|
||||
// edit FavoriteColors
|
||||
Enum enumm =
|
||||
(Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
Enum enumm = (Enum) dtm.getDataType(new CategoryPath("/MISC"), "FavoriteColors");
|
||||
enumm.remove("Red");
|
||||
enumm.remove("Black");
|
||||
enumm.add("Crimson", 6);
|
||||
|
|
|
@ -36,8 +36,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyOriginal(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
assertEquals(15, s.getLength());
|
||||
assertEquals(1, s.getAlignment());
|
||||
s.setToDefaultPacking();
|
||||
|
@ -55,8 +56,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyLatest(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
s.setToMachineAligned();
|
||||
|
||||
// Offsets change to 0,2,4,8.
|
||||
|
@ -72,8 +74,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyPrivate(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
s.setExplicitMinimumAlignment(4);
|
||||
|
||||
// Offsets change to 0,2,4,8.
|
||||
|
@ -168,8 +171,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyOriginal(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
assertEquals(15, s.getLength());
|
||||
assertEquals(1, s.getAlignment());
|
||||
s.setToDefaultPacking();
|
||||
|
@ -187,8 +191,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyLatest(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
s.pack(1);
|
||||
|
||||
// Offsets change to 0,2,4,8.
|
||||
|
@ -204,8 +209,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyPrivate(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
s.pack(2);
|
||||
|
||||
// Offsets change to 0,2,4,8.
|
||||
|
@ -230,9 +236,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
Structure s = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
assertTrue(s.hasExplicitPackingValue());
|
||||
assertEquals(1, s.getExplicitPackingValue());
|
||||
assertTrue(s.isDefaultAligned());
|
||||
|
@ -256,9 +261,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
Structure s = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
assertTrue(s.hasExplicitPackingValue());
|
||||
assertEquals(2, s.getExplicitPackingValue());
|
||||
assertTrue(s.isDefaultAligned());
|
||||
|
@ -303,8 +307,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyOriginal(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
assertEquals(15, s.getLength());
|
||||
assertEquals(1, s.getAlignment());
|
||||
s.setToDefaultPacking();
|
||||
|
@ -322,8 +327,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyLatest(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
s.setToMachineAligned();
|
||||
|
||||
// Offsets change to 0,2,4,8.
|
||||
|
@ -339,8 +345,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyPrivate(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
s.pack(1);
|
||||
|
||||
assertEquals(0, s.getComponent(0).getOffset());
|
||||
|
@ -364,9 +371,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
Structure s = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
assertTrue(s.hasDefaultPacking());
|
||||
assertTrue(s.isMachineAligned());
|
||||
|
||||
|
@ -389,9 +395,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
Structure s = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
assertTrue(s.hasExplicitPackingValue());
|
||||
assertEquals(1, s.getExplicitPackingValue());
|
||||
assertTrue(s.isDefaultAligned());
|
||||
|
@ -412,8 +417,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyLatest(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
assertEquals(15, s.getLength());
|
||||
assertEquals(1, s.getAlignment());
|
||||
s.add(new IntegerDataType());
|
||||
|
@ -433,8 +439,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyPrivate(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
assertEquals(15, s.getLength());
|
||||
assertEquals(1, s.getAlignment());
|
||||
s.setToDefaultPacking();
|
||||
|
@ -461,9 +468,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
Structure s = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
assertFalse(s.isPackingEnabled());
|
||||
assertTrue(s.isDefaultAligned());
|
||||
|
||||
|
@ -487,9 +493,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
Structure s = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
assertTrue(s.hasDefaultPacking());
|
||||
assertTrue(s.isDefaultAligned());
|
||||
|
||||
|
@ -509,8 +514,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyOriginal(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
assertEquals(15, s.getLength());
|
||||
assertEquals(1, s.getAlignment());
|
||||
s.setToDefaultPacking();
|
||||
|
@ -528,8 +534,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyLatest(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
assertEquals(16, s.getLength());
|
||||
assertEquals(4, s.getAlignment());
|
||||
s.getComponent(1).setFieldName("MyComponentOne");
|
||||
|
@ -550,8 +557,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyPrivate(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
assertEquals(16, s.getLength());
|
||||
assertEquals(4, s.getAlignment());
|
||||
s.pack(1);
|
||||
|
@ -577,9 +585,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
Structure s = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
assertTrue(s.hasDefaultPacking());
|
||||
assertTrue(s.isDefaultAligned());
|
||||
|
||||
|
@ -602,9 +609,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
Structure s = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
assertTrue(s.hasExplicitPackingValue());
|
||||
assertEquals(1, s.getExplicitPackingValue());
|
||||
assertTrue(s.isDefaultAligned());
|
||||
|
@ -625,8 +631,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyOriginal(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
assertEquals(15, s.getLength());
|
||||
assertEquals(1, s.getAlignment());
|
||||
s.setToDefaultPacking();
|
||||
|
@ -644,13 +651,15 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyLatest(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
dtm.remove(s, TaskMonitor.DUMMY);
|
||||
|
||||
// Offsets change to 0,2,4,8.
|
||||
Structure intStruct = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure intStruct =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
assertNull(intStruct);
|
||||
}
|
||||
|
||||
|
@ -658,8 +667,9 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyPrivate(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
s.pack(1);
|
||||
|
||||
assertEquals(0, s.getComponent(0).getOffset());
|
||||
|
@ -683,9 +693,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
Structure intStruct =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
Structure intStruct = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
assertNull(intStruct);
|
||||
}
|
||||
|
||||
|
@ -700,9 +709,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
Structure s = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
assertTrue(s.hasExplicitPackingValue());
|
||||
assertEquals(1, s.getExplicitPackingValue());
|
||||
assertTrue(s.isDefaultAligned());
|
||||
|
@ -723,12 +731,13 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyOriginal(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure s = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure s =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
s.setPackingEnabled(true);
|
||||
|
||||
Union union = (Union) dtm.getDataType(new CategoryPath("/Category1/Category2"),
|
||||
"CoolUnion");
|
||||
Union union =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
union.setPackingEnabled(true);
|
||||
}
|
||||
|
||||
|
@ -736,13 +745,14 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyLatest(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure structure = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure structure =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
assertEquals(16, structure.getLength());
|
||||
assertEquals(4, structure.getAlignment());
|
||||
|
||||
Union union = (Union) dtm.getDataType(new CategoryPath("/Category1/Category2"),
|
||||
"CoolUnion");
|
||||
Union union =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
assertEquals(96, union.getLength());
|
||||
assertEquals(4, union.getAlignment());
|
||||
|
||||
|
@ -753,13 +763,14 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyPrivate(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Structure structure = (Structure) dtm.getDataType(
|
||||
new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
Structure structure =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
assertEquals(16, structure.getLength());
|
||||
assertEquals(4, structure.getAlignment());
|
||||
|
||||
Union union = (Union) dtm.getDataType(new CategoryPath("/Category1/Category2"),
|
||||
"CoolUnion");
|
||||
Union union =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
assertEquals(96, union.getLength());
|
||||
assertEquals(4, union.getAlignment());
|
||||
|
||||
|
@ -774,44 +785,43 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
setupStructureInUnionAndViceVersa();
|
||||
executeMerge();
|
||||
|
||||
close(waitForWindow("Union Update Failed")); // expected dependency error on CoolUnion
|
||||
pressButtonByName(waitForWindow("Union Update Failed"), "OK"); // expected dependency error on CoolUnion
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
Structure intStruct =
|
||||
(Structure) dtm.getDataType(new CategoryPath("/Category1/Category2/Category3"),
|
||||
"IntStruct");
|
||||
assertTrue(intStruct.hasDefaultPacking());
|
||||
assertTrue(intStruct.isDefaultAligned());
|
||||
|
||||
assertEquals(5, intStruct.getNumComponents());
|
||||
assertEquals(0, intStruct.getComponent(0).getOffset());
|
||||
assertEquals(2, intStruct.getComponent(1).getOffset());
|
||||
assertEquals(4, intStruct.getComponent(2).getOffset());
|
||||
assertEquals(8, intStruct.getComponent(3).getOffset());
|
||||
assertEquals(16, intStruct.getComponent(4).getOffset());
|
||||
assertEquals("CoolUnion", intStruct.getComponent(4).getDataType().getDisplayName());
|
||||
assertEquals(112, intStruct.getLength());
|
||||
assertEquals(4, intStruct.getAlignment());
|
||||
Structure intStruct = (Structure) dtm
|
||||
.getDataType(new CategoryPath("/Category1/Category2/Category3"), "IntStruct");
|
||||
assertNotNull(intStruct);
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/Category3/IntStruct\n" +
|
||||
"pack()\n" +
|
||||
"Structure IntStruct {\n" +
|
||||
" 0 byte 1 field0 \"\"\n" +
|
||||
" 2 word 2 \"\"\n" +
|
||||
" 4 dword 4 \"\"\n" +
|
||||
" 8 qword 8 \"\"\n" +
|
||||
" 16 CoolUnion 112 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 128 Alignment: 4\n", intStruct.toString());
|
||||
//@formatter:on
|
||||
|
||||
Union coolUnion =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
assertTrue(coolUnion.hasDefaultPacking());
|
||||
assertTrue(coolUnion.isDefaultAligned());
|
||||
|
||||
assertEquals(6, coolUnion.getNumComponents());
|
||||
assertEquals("qword", coolUnion.getComponent(0).getDataType().getDisplayName());
|
||||
assertEquals("word", coolUnion.getComponent(1).getDataType().getDisplayName());
|
||||
assertEquals("undefined * * * * *",
|
||||
coolUnion.getComponent(2).getDataType().getDisplayName());
|
||||
assertEquals("DLL_Table", coolUnion.getComponent(3).getDataType().getDisplayName());
|
||||
assertEquals("DLL_Table *", coolUnion.getComponent(4).getDataType().getDisplayName());
|
||||
assertTrue(coolUnion.getComponent(5).getDataType() instanceof BadDataType);
|
||||
String comment5 = coolUnion.getComponent(5).getComment();
|
||||
assertTrue(comment5.startsWith("Couldn't add IntStruct here."));
|
||||
assertEquals(96, coolUnion.getLength());
|
||||
assertEquals(4, coolUnion.getAlignment());
|
||||
assertNotNull(coolUnion);
|
||||
//@formatter:off
|
||||
assertEquals("/Category1/Category2/CoolUnion\n" +
|
||||
"pack()\n" +
|
||||
"Union CoolUnion {\n" +
|
||||
" 0 qword 8 \"\"\n" +
|
||||
" 0 word 2 \"\"\n" +
|
||||
" 0 undefined * * * * * 4 \"\"\n" +
|
||||
" 0 DLL_Table 96 \"\"\n" +
|
||||
" 0 DLL_Table *32 4 \"\"\n" +
|
||||
" 0 -BAD- 112 \"Failed to apply 'IntStruct', Data type IntStruct has CoolUnion within it.\"\n" +
|
||||
"}\n" +
|
||||
"Length: 112 Alignment: 4\n", coolUnion.toString());
|
||||
//@formatter:on
|
||||
|
||||
}
|
||||
|
||||
|
@ -825,8 +835,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyOriginal(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Union union = (Union) dtm.getDataType(new CategoryPath("/Category1/Category2"),
|
||||
"CoolUnion");
|
||||
Union union =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
assertEquals(96, union.getLength());
|
||||
assertEquals(1, union.getAlignment());
|
||||
union.setPackingEnabled(true);
|
||||
|
@ -844,8 +854,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyLatest(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Union union = (Union) dtm.getDataType(new CategoryPath("/Category1/Category2"),
|
||||
"CoolUnion");
|
||||
Union union =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
union.setToMachineAligned();
|
||||
|
||||
assertEquals(8, union.getComponent(0).getLength());
|
||||
|
@ -861,8 +871,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyPrivate(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Union union = (Union) dtm.getDataType(new CategoryPath("/Category1/Category2"),
|
||||
"CoolUnion");
|
||||
Union union =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
union.setExplicitMinimumAlignment(4);
|
||||
|
||||
assertEquals(8, union.getComponent(0).getLength());
|
||||
|
@ -960,8 +970,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyOriginal(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Union union = (Union) dtm.getDataType(new CategoryPath("/Category1/Category2"),
|
||||
"CoolUnion");
|
||||
Union union =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
assertEquals(96, union.getLength());
|
||||
assertEquals(1, union.getAlignment());
|
||||
union.setPackingEnabled(true);
|
||||
|
@ -979,8 +989,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyLatest(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Union union = (Union) dtm.getDataType(new CategoryPath("/Category1/Category2"),
|
||||
"CoolUnion");
|
||||
Union union =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
union.pack(1);
|
||||
|
||||
assertEquals(8, union.getComponent(0).getLength());
|
||||
|
@ -996,8 +1006,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
public void modifyPrivate(ProgramDB program) throws Exception {
|
||||
DataTypeManager dtm = program.getDataTypeManager();
|
||||
|
||||
Union union = (Union) dtm.getDataType(new CategoryPath("/Category1/Category2"),
|
||||
"CoolUnion");
|
||||
Union union =
|
||||
(Union) dtm.getDataType(new CategoryPath("/Category1/Category2"), "CoolUnion");
|
||||
union.pack(2);
|
||||
|
||||
assertEquals(8, union.getComponent(0).getLength());
|
||||
|
@ -1116,8 +1126,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
assertEquals(4, s.getComponent(1).getOffset());
|
||||
assertEquals(4, s.getComponent(0).getLength());
|
||||
assertEquals(4, s.getComponent(1).getLength());
|
||||
assertTrue(new PointerDataType(new FloatDataType()).isEquivalent(
|
||||
s.getComponent(0).getDataType()));
|
||||
assertTrue(new PointerDataType(new FloatDataType())
|
||||
.isEquivalent(s.getComponent(0).getDataType()));
|
||||
assertTrue(new FloatDataType().isEquivalent(s.getComponent(1).getDataType()));
|
||||
|
||||
}
|
||||
|
@ -1154,8 +1164,8 @@ public class DataTypeMerge6Test extends AbstractDataTypeMergeTest {
|
|||
assertEquals(4, s1.getComponent(1).getOffset());
|
||||
assertEquals(4, s1.getComponent(0).getLength());
|
||||
assertEquals(4, s1.getComponent(1).getLength());
|
||||
assertTrue(new PointerDataType(new FloatDataType()).isEquivalent(
|
||||
s1.getComponent(0).getDataType()));
|
||||
assertTrue(new PointerDataType(new FloatDataType())
|
||||
.isEquivalent(s1.getComponent(0).getDataType()));
|
||||
assertTrue(new FloatDataType().isEquivalent(s1.getComponent(1).getDataType()));
|
||||
|
||||
Structure s2 =
|
||||
|
|
|
@ -95,7 +95,7 @@ public class DataTypeMergeFixupTest extends AbstractDataTypeMergeTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveInnerAddOuterChangeInnerPickLatest() throws Exception {
|
||||
public void testRemoveInnerAddOuterChangeInnerPickLatest() throws Exception {
|
||||
|
||||
final CategoryPath rootPath = new CategoryPath("/");
|
||||
|
||||
|
@ -105,25 +105,29 @@ public class DataTypeMergeFixupTest extends AbstractDataTypeMergeTest {
|
|||
|
||||
chooseOption(DataTypeMergeManager.OPTION_LATEST);
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
StructureInternal inner = (StructureInternal) dtm.getDataType(rootPath, "inner");
|
||||
assertNull(inner);
|
||||
|
||||
StructureInternal outer = (StructureInternal) dtm.getDataType(rootPath, "outer");
|
||||
assertNotNull(outer);
|
||||
assertEquals(true, outer.isPackingEnabled());
|
||||
assertEquals(true, outer.isDefaultAligned());
|
||||
assertEquals(CompositeInternal.DEFAULT_ALIGNMENT, outer.getStoredMinimumAlignment());
|
||||
assertEquals(CompositeInternal.DEFAULT_PACKING, outer.getStoredPackingValue());
|
||||
assertEquals(1, outer.getNumComponents());
|
||||
assertTrue(new ByteDataType().isEquivalent(outer.getComponent(0).getDataType()));
|
||||
assertEquals(1, outer.getLength());
|
||||
assertEquals(1, outer.getAlignment());
|
||||
//@formatter:off
|
||||
assertEquals("/outer\n" +
|
||||
"pack()\n" +
|
||||
"Structure outer {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 -BAD- 4 \"Failed to apply 'inner'\"\n" +
|
||||
"}\n" +
|
||||
"Length: 5 Alignment: 1\n", outer.toString());
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveInnerAddOuterChangeInnerPickMy() throws Exception {
|
||||
public void testRemoveInnerAddOuterChangeInnerPickMy() throws Exception {
|
||||
|
||||
final CategoryPath rootPath = new CategoryPath("/");
|
||||
|
||||
|
@ -163,7 +167,7 @@ public class DataTypeMergeFixupTest extends AbstractDataTypeMergeTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveInnerVsAddOuterContainingInner() throws Exception {
|
||||
public void testRemoveInnerVsAddOuterContainingInner() throws Exception {
|
||||
|
||||
final CategoryPath rootPath = new CategoryPath("/");
|
||||
|
||||
|
@ -227,25 +231,29 @@ public class DataTypeMergeFixupTest extends AbstractDataTypeMergeTest {
|
|||
|
||||
executeMerge();
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
StructureInternal inner = (StructureInternal) dtm.getDataType(rootPath, "inner");
|
||||
assertNull(inner);
|
||||
|
||||
StructureInternal outer = (StructureInternal) dtm.getDataType(rootPath, "outer");
|
||||
assertNotNull(outer);
|
||||
assertEquals(true, outer.isPackingEnabled());
|
||||
assertEquals(true, outer.isDefaultAligned());
|
||||
assertEquals(CompositeInternal.DEFAULT_ALIGNMENT, outer.getStoredMinimumAlignment());
|
||||
assertEquals(CompositeInternal.DEFAULT_PACKING, outer.getStoredPackingValue());
|
||||
assertEquals(1, outer.getNumComponents());
|
||||
assertTrue(new ByteDataType().isEquivalent(outer.getComponent(0).getDataType()));
|
||||
assertEquals(1, outer.getLength());
|
||||
assertEquals(1, outer.getAlignment());
|
||||
//@formatter:off
|
||||
assertEquals("/outer\n" +
|
||||
"pack()\n" +
|
||||
"Structure outer {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 -BAD- 4 \"Failed to apply 'inner'\"\n" +
|
||||
"}\n" +
|
||||
"Length: 5 Alignment: 1\n", outer.toString());
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveInnerVsAddOuterWithOtherAfterInner() throws Exception {
|
||||
public void testRemoveInnerVsAddOuterWithOtherAfterInner() throws Exception {
|
||||
|
||||
final CategoryPath rootPath = new CategoryPath("/");
|
||||
|
||||
|
@ -323,6 +331,8 @@ public class DataTypeMergeFixupTest extends AbstractDataTypeMergeTest {
|
|||
|
||||
executeMerge();
|
||||
|
||||
dismissUnresolvedDataTypesPopup();
|
||||
|
||||
waitForCompletion();
|
||||
|
||||
DataTypeManager dtm = resultProgram.getDataTypeManager();
|
||||
|
@ -332,31 +342,30 @@ public class DataTypeMergeFixupTest extends AbstractDataTypeMergeTest {
|
|||
|
||||
StructureInternal other = (StructureInternal) dtm.getDataType(rootPath, "other");
|
||||
assertNotNull(other);
|
||||
assertEquals(true, other.isPackingEnabled());
|
||||
assertEquals(true, other.isDefaultAligned());
|
||||
assertEquals(CompositeInternal.DEFAULT_ALIGNMENT, other.getStoredMinimumAlignment());
|
||||
assertEquals(CompositeInternal.DEFAULT_PACKING, other.getStoredPackingValue());
|
||||
assertEquals(2, other.getNumComponents());
|
||||
assertTrue(new ByteDataType().isEquivalent(other.getComponent(0).getDataType()));
|
||||
assertTrue(new PointerDataType(new VoidDataType()).isEquivalent(
|
||||
other.getComponent(1).getDataType()));
|
||||
assertEquals(8, other.getLength());
|
||||
assertEquals(4, other.getAlignment());
|
||||
//@formatter:off
|
||||
assertEquals("/other\n" +
|
||||
"pack()\n" +
|
||||
"Structure other {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 4 void * 4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 4\n", other.toString());
|
||||
//@formatter:on
|
||||
|
||||
StructureInternal outer = (StructureInternal) dtm.getDataType(rootPath, "outer");
|
||||
assertNotNull(outer);
|
||||
assertEquals(true, outer.isPackingEnabled());
|
||||
assertEquals(true, outer.isDefaultAligned());
|
||||
assertEquals(CompositeInternal.DEFAULT_ALIGNMENT, outer.getStoredMinimumAlignment());
|
||||
assertEquals(CompositeInternal.DEFAULT_PACKING, outer.getStoredPackingValue());
|
||||
assertEquals(4, outer.getNumComponents());
|
||||
assertTrue(new ByteDataType().isEquivalent(outer.getComponent(0).getDataType()));
|
||||
assertTrue(new FloatDataType().isEquivalent(outer.getComponent(1).getDataType()));
|
||||
assertEquals(other, outer.getComponent(2).getDataType());
|
||||
assertTrue(new ByteDataType().isEquivalent(outer.getComponent(3).getDataType()));
|
||||
assertEquals(4, outer.getComponent(1).getLength());
|
||||
assertEquals(20, outer.getLength());
|
||||
assertEquals(4, outer.getAlignment());
|
||||
//@formatter:off
|
||||
assertEquals("/outer\n" +
|
||||
"pack()\n" +
|
||||
"Structure outer {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 -BAD- 4 \"Failed to apply 'inner'\"\n" +
|
||||
" 8 float 4 \"\"\n" +
|
||||
" 12 other 8 \"\"\n" +
|
||||
" 20 byte 1 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 24 Alignment: 4\n", outer.toString());
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
package ghidra.app.merge.listing;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -44,15 +44,8 @@ public class BookmarkMergerNoteTest extends AbstractListingMergeManagerTest {
|
|||
@Override
|
||||
protected ProgramMultiUserMergeManager createMergeManager(ProgramChangeSet resultChangeSet,
|
||||
ProgramChangeSet myChangeSet) {
|
||||
|
||||
// NOTE: this makes the tests faster. If you need visual debugging, then make this true
|
||||
boolean showListingPanels = false;
|
||||
|
||||
ProgramMultiUserMergeManager mergeManger =
|
||||
new ProgramMultiUserMergeManager(resultProgram, myProgram, originalProgram,
|
||||
latestProgram, resultChangeSet, myChangeSet, showListingPanels);
|
||||
|
||||
return mergeManger;
|
||||
return new ProgramMultiUserMergeManager(resultProgram, myProgram, originalProgram,
|
||||
latestProgram, resultChangeSet, myChangeSet);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -74,15 +74,8 @@ public class ExternalMergerAddTest extends AbstractExternalMergerTest {
|
|||
@Override
|
||||
protected ProgramMultiUserMergeManager createMergeManager(ProgramChangeSet resultChangeSet,
|
||||
ProgramChangeSet myChangeSet) {
|
||||
|
||||
// NOTE: this makes the tests faster. If you need visual debugging, then make this true
|
||||
boolean showListingPanels = false;
|
||||
|
||||
ProgramMultiUserMergeManager mergeManger =
|
||||
new ProgramMultiUserMergeManager(resultProgram, myProgram, originalProgram,
|
||||
latestProgram, resultChangeSet, myChangeSet, showListingPanels);
|
||||
|
||||
return mergeManger;
|
||||
return new ProgramMultiUserMergeManager(resultProgram, myProgram, originalProgram,
|
||||
latestProgram, resultChangeSet, myChangeSet);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -2103,8 +2096,9 @@ public class ExternalMergerAddTest extends AbstractExternalMergerTest {
|
|||
|
||||
Namespace externalLibrary =
|
||||
(Namespace) resultProgram.getSymbolTable().getLibrarySymbol(libname).getObject();
|
||||
Namespace myNamespace = (Namespace) getUniqueSymbol(resultProgram, parentNamespace,
|
||||
externalLibrary).getObject();
|
||||
Namespace myNamespace =
|
||||
(Namespace) getUniqueSymbol(resultProgram, parentNamespace, externalLibrary)
|
||||
.getObject();
|
||||
Symbol blue = getUniqueSymbol(resultProgram, namespace1, myNamespace);
|
||||
Symbol blueConflict =
|
||||
getUniqueSymbol(resultProgram, namespace1 + "_conflict1", myNamespace);
|
||||
|
@ -2167,8 +2161,9 @@ public class ExternalMergerAddTest extends AbstractExternalMergerTest {
|
|||
Namespace externalLibrary =
|
||||
(Namespace) resultProgram.getSymbolTable().getLibrarySymbol(libname).getObject();
|
||||
assertNotNull(externalLibrary);
|
||||
Namespace myNamespace = (Namespace) getUniqueSymbol(resultProgram, parentNamespace,
|
||||
externalLibrary).getObject();
|
||||
Namespace myNamespace =
|
||||
(Namespace) getUniqueSymbol(resultProgram, parentNamespace, externalLibrary)
|
||||
.getObject();
|
||||
assertNotNull(myNamespace);
|
||||
Symbol apples = getUniqueSymbol(resultProgram, label, myNamespace);
|
||||
Symbol applesConflict = getUniqueSymbol(resultProgram, label + "_conflict1", myNamespace);
|
||||
|
@ -2221,8 +2216,9 @@ public class ExternalMergerAddTest extends AbstractExternalMergerTest {
|
|||
Namespace externalLibrary =
|
||||
(Namespace) resultProgram.getSymbolTable().getLibrarySymbol(libname).getObject();
|
||||
assertNotNull(externalLibrary);
|
||||
Namespace myNamespace = (Namespace) getUniqueSymbol(resultProgram, parentNamespace,
|
||||
externalLibrary).getObject();
|
||||
Namespace myNamespace =
|
||||
(Namespace) getUniqueSymbol(resultProgram, parentNamespace, externalLibrary)
|
||||
.getObject();
|
||||
assertNotNull(myNamespace);
|
||||
Symbol apples = getUniqueSymbol(resultProgram, label1, myNamespace);
|
||||
Symbol oranges = getUniqueSymbol(resultProgram, label2, myNamespace);
|
||||
|
@ -2296,8 +2292,9 @@ public class ExternalMergerAddTest extends AbstractExternalMergerTest {
|
|||
Namespace externalLibrary =
|
||||
(Namespace) resultProgram.getSymbolTable().getLibrarySymbol(libname).getObject();
|
||||
assertNotNull(externalLibrary);
|
||||
Namespace myNamespace = (Namespace) getUniqueSymbol(resultProgram, parentNamespace,
|
||||
externalLibrary).getObject();
|
||||
Namespace myNamespace =
|
||||
(Namespace) getUniqueSymbol(resultProgram, parentNamespace, externalLibrary)
|
||||
.getObject();
|
||||
assertNotNull(myNamespace);
|
||||
Symbol apples = getUniqueSymbol(resultProgram, label, myNamespace);
|
||||
Symbol applesConflict = getUniqueSymbol(resultProgram, label + "_conflict1", myNamespace);
|
||||
|
@ -2361,8 +2358,9 @@ public class ExternalMergerAddTest extends AbstractExternalMergerTest {
|
|||
Namespace externalLibrary =
|
||||
(Namespace) resultProgram.getSymbolTable().getLibrarySymbol(libname).getObject();
|
||||
assertNotNull(externalLibrary);
|
||||
Namespace myNamespace = (Namespace) getUniqueSymbol(resultProgram, parentNamespace,
|
||||
externalLibrary).getObject();
|
||||
Namespace myNamespace =
|
||||
(Namespace) getUniqueSymbol(resultProgram, parentNamespace, externalLibrary)
|
||||
.getObject();
|
||||
assertNotNull(myNamespace);
|
||||
Symbol apples = getUniqueSymbol(resultProgram, label, myNamespace);
|
||||
Symbol applesConflict = getUniqueSymbol(resultProgram, label + "_conflict1", myNamespace);
|
||||
|
@ -2501,8 +2499,9 @@ public class ExternalMergerAddTest extends AbstractExternalMergerTest {
|
|||
Namespace externalLibrary =
|
||||
(Namespace) resultProgram.getSymbolTable().getLibrarySymbol(libname).getObject();
|
||||
assertNotNull(externalLibrary);
|
||||
Namespace myNamespace = (Namespace) getUniqueSymbol(resultProgram, parentNamespace,
|
||||
externalLibrary).getObject();
|
||||
Namespace myNamespace =
|
||||
(Namespace) getUniqueSymbol(resultProgram, parentNamespace, externalLibrary)
|
||||
.getObject();
|
||||
assertNotNull(myNamespace);
|
||||
Symbol apples = getUniqueSymbol(resultProgram, label, myNamespace);
|
||||
Symbol applesConflict = getUniqueSymbol(resultProgram, label + "_conflict1", myNamespace);
|
||||
|
@ -2585,8 +2584,9 @@ public class ExternalMergerAddTest extends AbstractExternalMergerTest {
|
|||
Namespace externalLibrary =
|
||||
(Namespace) resultProgram.getSymbolTable().getLibrarySymbol(libname).getObject();
|
||||
assertNotNull(externalLibrary);
|
||||
Namespace myNamespace = (Namespace) getUniqueSymbol(resultProgram, parentNamespace,
|
||||
externalLibrary).getObject();
|
||||
Namespace myNamespace =
|
||||
(Namespace) getUniqueSymbol(resultProgram, parentNamespace, externalLibrary)
|
||||
.getObject();
|
||||
assertNotNull(myNamespace);
|
||||
Symbol apples = getUniqueSymbol(resultProgram, label, myNamespace);
|
||||
Symbol applesConflict = getUniqueSymbol(resultProgram, label + "_conflict1", myNamespace);
|
||||
|
@ -2780,8 +2780,9 @@ public class ExternalMergerAddTest extends AbstractExternalMergerTest {
|
|||
Namespace externalLibrary =
|
||||
(Namespace) resultProgram.getSymbolTable().getLibrarySymbol(libname).getObject();
|
||||
assertNotNull(externalLibrary);
|
||||
Namespace myNamespace = (Namespace) getUniqueSymbol(resultProgram, parentNamespace,
|
||||
externalLibrary).getObject();
|
||||
Namespace myNamespace =
|
||||
(Namespace) getUniqueSymbol(resultProgram, parentNamespace, externalLibrary)
|
||||
.getObject();
|
||||
assertNotNull(myNamespace);
|
||||
Symbol apples = getUniqueSymbol(resultProgram, label, myNamespace);
|
||||
Symbol applesConflict = getUniqueSymbol(resultProgram, label + "_conflict1", myNamespace);
|
||||
|
@ -2863,8 +2864,9 @@ public class ExternalMergerAddTest extends AbstractExternalMergerTest {
|
|||
Namespace externalLibrary =
|
||||
(Namespace) resultProgram.getSymbolTable().getLibrarySymbol(libname).getObject();
|
||||
assertNotNull(externalLibrary);
|
||||
Namespace myNamespace = (Namespace) getUniqueSymbol(resultProgram, parentNamespace,
|
||||
externalLibrary).getObject();
|
||||
Namespace myNamespace =
|
||||
(Namespace) getUniqueSymbol(resultProgram, parentNamespace, externalLibrary)
|
||||
.getObject();
|
||||
assertNotNull(myNamespace);
|
||||
Symbol apples = getUniqueSymbol(resultProgram, label, myNamespace);
|
||||
Symbol applesConflict = getUniqueSymbol(resultProgram, label + "_conflict1", myNamespace);
|
||||
|
@ -2948,8 +2950,9 @@ public class ExternalMergerAddTest extends AbstractExternalMergerTest {
|
|||
Namespace externalLibrary =
|
||||
(Namespace) resultProgram.getSymbolTable().getLibrarySymbol(libname).getObject();
|
||||
assertNotNull(externalLibrary);
|
||||
Namespace myNamespace = (Namespace) getUniqueSymbol(resultProgram, parentNamespace,
|
||||
externalLibrary).getObject();
|
||||
Namespace myNamespace =
|
||||
(Namespace) getUniqueSymbol(resultProgram, parentNamespace, externalLibrary)
|
||||
.getObject();
|
||||
|
||||
List<Symbol> symbols = symbolTable.getSymbols(label, myNamespace);
|
||||
assertEquals(2, symbols.size());
|
||||
|
|
|
@ -84,9 +84,9 @@ public class StructureEditorNotifiedTest extends AbstractStructureEditorTest {
|
|||
init(complexStructure, tempCat);
|
||||
int num = model.getNumComponents();
|
||||
int len = model.getLength();
|
||||
DataType dataType10 = model.viewComposite.getComponent(10).getDataType();
|
||||
DataType dataType10 = getDataType(10);
|
||||
assertEquals("complexStructure *", dataType10.getDisplayName());
|
||||
assertEquals(4, dataType10.getLength());
|
||||
assertEquals(4, getLength(10));
|
||||
|
||||
programDTM.remove(complexStructure, TaskMonitor.DUMMY);
|
||||
programDTM.getCategory(pgmRootCat.getCategoryPath())
|
||||
|
@ -97,12 +97,12 @@ public class StructureEditorNotifiedTest extends AbstractStructureEditorTest {
|
|||
|
||||
waitForSwing();
|
||||
|
||||
// complexStructure* gets removed and becomes 4 undefined bytes in this editor.
|
||||
assertEquals(num + 3, model.getNumComponents());
|
||||
// complexStructure* gets removed and becomes BadDataType in this editor.
|
||||
assertEquals(num, model.getNumComponents());
|
||||
assertEquals(len, model.getLength());
|
||||
dataType10 = model.viewComposite.getComponent(10).getDataType();
|
||||
assertEquals("undefined", dataType10.getDisplayName());
|
||||
assertEquals(1, dataType10.getLength());
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(10)));
|
||||
assertEquals("Type 'complexStructure *' was deleted", getComment(10));
|
||||
assertEquals(4, getLength(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -498,25 +498,31 @@ public class StructureEditorNotifiedTest extends AbstractStructureEditorTest {
|
|||
DataType dt10 = getDataType(complexStructure, 10);
|
||||
|
||||
init(complexStructure, pgmTestCat);
|
||||
DataType undef = DataType.DEFAULT;
|
||||
|
||||
assertEquals(1, getLength(9)); // length start-off wierd - not sure why
|
||||
|
||||
assertEquals(23, model.getNumComponents());
|
||||
assertEquals(0x145, model.getLength());
|
||||
|
||||
runSwing(
|
||||
() -> complexStructure.getDataTypeManager().remove(simpleUnion, TaskMonitor.DUMMY));
|
||||
waitForSwing();
|
||||
assertEquals(30, model.getNumComponents());
|
||||
assertEquals(23, model.getNumComponents());
|
||||
assertTrue(dt3.isEquivalent(getDataType(3)));
|
||||
assertTrue(undef.isEquivalent(getDataType(4)));
|
||||
assertTrue(undef.isEquivalent(getDataType(11)));
|
||||
assertTrue(dt5.isEquivalent(getDataType(12)));
|
||||
assertTrue(dt8.isEquivalent(getDataType(15)));
|
||||
assertTrue(undef.isEquivalent(getDataType(16)));
|
||||
assertTrue(dt10.isEquivalent(getDataType(17)));
|
||||
assertEquals(4, getOffset(3));
|
||||
assertEquals(16, getOffset(12));
|
||||
assertEquals(24, getOffset(15));
|
||||
assertEquals(33, getOffset(17));
|
||||
assertEquals(0x8, getLength(4));
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(4)));
|
||||
assertEquals("Type 'simpleUnion' was deleted", getComment(4));
|
||||
assertTrue(dt5.isEquivalent(getDataType(5)));
|
||||
assertTrue(dt8.isEquivalent(getDataType(8)));
|
||||
assertEquals(0x20, getOffset(9));
|
||||
assertEquals(1, getLength(9)); // length start-off wierd
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(9)));
|
||||
assertEquals("Type 'simpleUnion *' was deleted", getComment(9));
|
||||
assertEquals(0x21, getOffset(10));
|
||||
assertEquals(0x4, getLength(10));
|
||||
assertTrue(dt10.isEquivalent(getDataType(10)));
|
||||
assertEquals(0x145, model.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -525,12 +531,17 @@ public class StructureEditorNotifiedTest extends AbstractStructureEditorTest {
|
|||
|
||||
runSwingWithException(() -> model.add(simpleStructure));
|
||||
waitForSwing();
|
||||
|
||||
assertEquals(1, model.getNumComponents());
|
||||
assertTrue(simpleStructure.isEquivalent(getDataType(0)));
|
||||
|
||||
runSwing(
|
||||
() -> simpleStructure.getDataTypeManager().remove(simpleStructure, TaskMonitor.DUMMY));
|
||||
waitForSwing();
|
||||
assertEquals(29, model.getNumComponents());// becomes undefined bytes
|
||||
|
||||
assertEquals(1, model.getNumComponents());// component becomes BadDataType
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(0)));
|
||||
assertEquals("Type 'simpleStructure' was deleted", getComment(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -299,14 +299,26 @@ public class StructureEditorProviderTest extends AbstractStructureEditorTest {
|
|||
dialog = getWindow("Close Structure Editor?");
|
||||
assertNull(dialog);
|
||||
|
||||
// Verify the editor provider remains visible with myStructure use converted to BadDataType.
|
||||
assertEquals(1, model.viewComposite.getNumComponents());
|
||||
assertEquals(1, model.viewComposite.getNumDefinedComponents());
|
||||
DataTypeComponent dtc = model.viewComposite.getComponent(0);
|
||||
assertTrue(BadDataType.dataType.isEquivalent(dtc.getDataType()));
|
||||
assertEquals(2, dtc.getLength());
|
||||
|
||||
runSwing(() -> {
|
||||
model.deleteComponent(0);
|
||||
});
|
||||
waitForSwing();
|
||||
|
||||
assertTrue(
|
||||
isProviderShown(tool.getToolFrame(), "Structure Editor", "emptyStructure (Test)"));
|
||||
|
||||
// Verify the editor provider remains visible with myStructure use cleared.
|
||||
assertFalse(emptyStructure.isEquivalent(model.viewComposite));
|
||||
// Verify the editor provider remains visible with BadDataType use cleared.
|
||||
assertTrue(emptyStructure.isEquivalent(model.viewComposite));
|
||||
assertFalse(dtCopy.isEquivalent(model.viewComposite));
|
||||
assertEquals(dtCopy.getLength(), model.viewComposite.getLength());
|
||||
assertEquals(2, model.viewComposite.getNumComponents());
|
||||
assertTrue(model.viewComposite.isZeroLength());
|
||||
assertEquals(0, model.viewComposite.getNumComponents());
|
||||
assertEquals(0, model.viewComposite.getNumDefinedComponents());
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,8 @@ public class UnionEditorNotifiedTest extends AbstractUnionEditorTest {
|
|||
init(complexUnion, tempCat, false);
|
||||
|
||||
int num = model.getNumComponents();
|
||||
int len = model.getLength();
|
||||
|
||||
// Clone the data types we want to hold onto for comparison later, since reload can close the viewDTM.
|
||||
DataType dt18 = getDataType(18).clone(programDTM);
|
||||
DataType dt20 = getDataType(20).clone(programDTM);
|
||||
|
@ -128,9 +130,13 @@ public class UnionEditorNotifiedTest extends AbstractUnionEditorTest {
|
|||
dialog = null;
|
||||
|
||||
// refUnion* gets removed
|
||||
assertEquals(num - 1, model.getNumComponents());
|
||||
assertEquals(num, model.getNumComponents());
|
||||
assertEquals(len, model.getLength());
|
||||
assertTrue(dt18.isEquivalent(getDataType(18)));
|
||||
assertTrue(dt20.isEquivalent(getDataType(19)));
|
||||
assertEquals(4, getLength(19));
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(19)));
|
||||
assertEquals("Type 'refUnion *' was deleted", getComment(19));
|
||||
assertTrue(dt20.isEquivalent(getDataType(20)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -303,10 +309,38 @@ public class UnionEditorNotifiedTest extends AbstractUnionEditorTest {
|
|||
init(complexUnion, pgmTestCat, false);
|
||||
|
||||
assertEquals(21, model.getNumComponents());
|
||||
assertEquals(4, getLength(5));
|
||||
assertEquals(0x57, getLength(12));
|
||||
assertEquals(0x38, getLength(13));
|
||||
assertEquals(0x1d, getLength(15));
|
||||
assertEquals(0x18, getLength(17));
|
||||
assertEquals(0x1d, getLength(20));
|
||||
assertEquals(21, model.getNumComponents());
|
||||
assertEquals(0x57, model.getLength());
|
||||
|
||||
SwingUtilities.invokeLater(
|
||||
() -> complexUnion.getDataTypeManager().remove(simpleStructure, TaskMonitor.DUMMY));
|
||||
waitForSwing();
|
||||
assertEquals(15, model.getNumComponents());
|
||||
|
||||
assertEquals(21, model.getNumComponents());
|
||||
assertEquals(4, getLength(5));
|
||||
assertEquals(0x57, getLength(12));
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(12)));
|
||||
assertEquals("Type 'simpleStructure[3]' was deleted", getComment(12));
|
||||
assertEquals(0x38, getLength(13));
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(13)));
|
||||
assertEquals("Type 'simpleStructure *[7]' was deleted", getComment(13));
|
||||
assertEquals(0x1d, getLength(15));
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(15)));
|
||||
assertEquals("Type 'simpleStructureTypedef' was deleted", getComment(15));
|
||||
assertEquals(0x18, getLength(17));
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(17)));
|
||||
assertEquals("Type 'simpleStructureTypedef * *[2][3]' was deleted", getComment(17));
|
||||
assertEquals(0x1d, getLength(20));
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(20)));
|
||||
assertEquals("Type 'simpleStructure' was deleted", getComment(20));
|
||||
assertEquals(21, model.getNumComponents());
|
||||
assertEquals(0x57, model.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -322,12 +356,20 @@ public class UnionEditorNotifiedTest extends AbstractUnionEditorTest {
|
|||
}
|
||||
});
|
||||
waitForSwing();
|
||||
assertEquals(1, model.getNumComponents());
|
||||
assertTrue(simpleUnion.isEquivalent(getDataType(0)));
|
||||
assertEquals(8, getLength(0));
|
||||
assertEquals(8, model.getLength());
|
||||
|
||||
SwingUtilities.invokeLater(
|
||||
() -> simpleUnion.getDataTypeManager().remove(simpleUnion, TaskMonitor.DUMMY));
|
||||
waitForSwing();
|
||||
assertEquals(0, model.getNumComponents());
|
||||
|
||||
assertEquals(1, model.getNumComponents());
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(0)));
|
||||
assertEquals("Type 'simpleUnion' was deleted", getComment(0));
|
||||
assertEquals(8, getLength(0));
|
||||
assertEquals(8, model.getLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -335,6 +377,7 @@ public class UnionEditorNotifiedTest extends AbstractUnionEditorTest {
|
|||
init(complexUnion, pgmTestCat, false);
|
||||
|
||||
int num = model.getNumComponents();
|
||||
int len = model.getLength();
|
||||
|
||||
// Clone the data types we want to hold onto for comparison later, since reload can close the viewDTM.
|
||||
DataType dt18 = getDataType(18).clone(programDTM);
|
||||
|
@ -347,19 +390,38 @@ public class UnionEditorNotifiedTest extends AbstractUnionEditorTest {
|
|||
SwingUtilities.invokeLater(() -> dtm.remove(refUnion, TaskMonitor.DUMMY)); // remove refUnion
|
||||
waitForSwing();
|
||||
|
||||
// refUnion* gets removed (1 component)
|
||||
num -= 1;
|
||||
// refUnion* gets removed
|
||||
assertEquals(len, model.getLength());
|
||||
assertEquals(num, model.getNumComponents());
|
||||
|
||||
assertEquals(1, getLength(8)); // weird length
|
||||
|
||||
assertTrue(dt18.isEquivalent(getDataType(18)));
|
||||
assertTrue(dt20.isEquivalent(getDataType(19)));
|
||||
assertEquals(4, getLength(19));
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(19)));
|
||||
assertEquals("Type 'refUnion *' was deleted", getComment(19));
|
||||
assertTrue(dt20.isEquivalent(getDataType(20)));
|
||||
|
||||
SwingUtilities.invokeLater(
|
||||
() -> simpleUnion.getDataTypeManager().remove(simpleUnion, TaskMonitor.DUMMY));
|
||||
waitForSwing();
|
||||
|
||||
// All components (3 total) which were dependent upon simpleUnion are removed
|
||||
num -= 3;
|
||||
assertEquals(len, model.getLength());
|
||||
assertEquals(num, model.getNumComponents());
|
||||
|
||||
assertEquals(8, getLength(3));
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(3)));
|
||||
assertEquals("Type 'simpleUnion' was deleted", getComment(3));
|
||||
assertEquals(1, getLength(8)); // length was weird to start with
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(8)));
|
||||
assertEquals("Type 'simpleUnion *' was deleted", getComment(8));
|
||||
assertEquals(8, getLength(16));
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(16)));
|
||||
assertEquals("Type 'simpleUnionTypedef' was deleted", getComment(16));
|
||||
assertEquals(4, getLength(19));
|
||||
assertTrue(BadDataType.dataType.isEquivalent(getDataType(19)));
|
||||
assertEquals("Type 'refUnion *' was deleted", getComment(19));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -573,9 +573,30 @@ public class CategoryTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
DataType cdt = root.getDataType("InnerStruct");
|
||||
assertNotNull(cdt);
|
||||
|
||||
//@formatter:off
|
||||
assertEquals("/SubCat-A/Sub-cat/MyStruct\n" + "pack(disabled)\n" +
|
||||
"Structure MyStruct {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 word 2 \"\"\n" +
|
||||
" 3 byte 1 \"\"\n" +
|
||||
" 4 InnerStruct 31 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 135 Alignment: 1\n", newDt.toString());
|
||||
//@formatter:on
|
||||
|
||||
root.remove(cdt, monitor);
|
||||
|
||||
assertEquals(comps.length - 1, newDt.getDefinedComponents().length);
|
||||
//@formatter:off
|
||||
assertEquals("/SubCat-A/Sub-cat/MyStruct\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure MyStruct {\n" +
|
||||
" 0 byte 1 \"\"\n" +
|
||||
" 1 word 2 \"\"\n" +
|
||||
" 3 byte 1 \"\"\n" +
|
||||
" 4 -BAD- 31 \"Type 'InnerStruct' was deleted\"\n" +
|
||||
"}\n" +
|
||||
"Length: 135 Alignment: 1\n", newDt.toString());
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.commons.compress.utils.Sets;
|
|||
import org.junit.*;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
|
||||
public class StructureDataTypeTest extends AbstractGenericTest {
|
||||
|
||||
|
@ -1070,8 +1071,8 @@ public class StructureDataTypeTest extends AbstractGenericTest {
|
|||
assertEquals(2, struct.getNumDefinedComponents());
|
||||
|
||||
len /= 2;
|
||||
struct.replaceAtOffset(len-2, WordDataType.dataType, -1, "x", null); // will be preserved below
|
||||
struct.replaceAtOffset(len+2, WordDataType.dataType, -1, "y", null); // will be cleared below
|
||||
struct.replaceAtOffset(len - 2, WordDataType.dataType, -1, "x", null); // will be preserved below
|
||||
struct.replaceAtOffset(len + 2, WordDataType.dataType, -1, "y", null); // will be cleared below
|
||||
struct.setLength(len);
|
||||
assertEquals(len, struct.getLength());
|
||||
assertEquals(len - 2, struct.getNumComponents());
|
||||
|
@ -1393,15 +1394,34 @@ public class StructureDataTypeTest extends AbstractGenericTest {
|
|||
|
||||
struct.add(s);
|
||||
|
||||
DataTypeComponent[] dtc = struct.getComponents();
|
||||
assertEquals(5, dtc.length);
|
||||
//@formatter:off
|
||||
CompositeTestUtils.assertExpectedComposite(this, "/TestStruct\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure TestStruct {\n" +
|
||||
" 0 byte 1 field1 \"Comment1\"\n" +
|
||||
" 1 word 2 \"Comment2\"\n" +
|
||||
" 3 dword 4 field3 \"\"\n" +
|
||||
" 7 byte 1 field4 \"Comment4\"\n" +
|
||||
" 8 test1 5 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 13 Alignment: 1", struct);
|
||||
//@formatter:on
|
||||
|
||||
struct.dataTypeDeleted(s);
|
||||
|
||||
dtc = struct.getComponents();
|
||||
assertEquals(9, dtc.length);
|
||||
//@formatter:off
|
||||
CompositeTestUtils.assertExpectedComposite(this, "/TestStruct\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure TestStruct {\n" +
|
||||
" 0 byte 1 field1 \"Comment1\"\n" +
|
||||
" 1 word 2 \"Comment2\"\n" +
|
||||
" 3 dword 4 field3 \"\"\n" +
|
||||
" 7 byte 1 field4 \"Comment4\"\n" +
|
||||
" 8 -BAD- 5 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 13 Alignment: 1", struct);
|
||||
//@formatter:on
|
||||
|
||||
assertEquals(9, struct.getNumComponents());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -56,7 +56,8 @@ class BitFieldDBDataType extends BitFieldDataType {
|
|||
* bit size may be reduced based upon the specified base datatype size.
|
||||
* @param bitOffset right shift factor within storage unit when viewed as a big-endian dd
|
||||
* scalar value. Based upon minimal storage bitOffset should be in the range 0 to 7.
|
||||
* @throws InvalidDataTypeException
|
||||
* @throws InvalidDataTypeException if invalid base datatype has been specified or an
|
||||
* invalid bitSize or bitOffset has been specified
|
||||
*/
|
||||
BitFieldDBDataType(DataType baseDataType, int bitSize, int bitOffset)
|
||||
throws InvalidDataTypeException {
|
||||
|
@ -66,6 +67,7 @@ class BitFieldDBDataType extends BitFieldDataType {
|
|||
|
||||
private static enum BaseDatatypeKind {
|
||||
NONE(0), TYPEDEF(1), ENUM(2), INTEGER(3);
|
||||
|
||||
final int id;
|
||||
|
||||
BaseDatatypeKind(int id) {
|
||||
|
|
|
@ -156,25 +156,23 @@ abstract class CompositeDB extends DataTypeDB implements CompositeInternal {
|
|||
* @param oldDt affected datatype which has been removed or replaced
|
||||
* @param newDt replacement datatype
|
||||
* @return true if bitfield component was modified
|
||||
* @throws InvalidDataTypeException if bitfield was based upon oldDt but new
|
||||
* datatype is invalid for a bitfield
|
||||
*/
|
||||
protected boolean updateBitFieldDataType(DataTypeComponentDB bitfieldComponent, DataType oldDt,
|
||||
DataType newDt) throws InvalidDataTypeException {
|
||||
DataType newDt) {
|
||||
if (!bitfieldComponent.isBitFieldComponent()) {
|
||||
throw new AssertException("expected bitfield component");
|
||||
}
|
||||
|
||||
BitFieldDBDataType bitfieldDt = (BitFieldDBDataType) bitfieldComponent.getDataType();
|
||||
if (bitfieldDt.getBaseDataType() != oldDt) {
|
||||
if (bitfieldDt.getBaseDataType() != oldDt || !BitFieldDataType.isValidBaseDataType(newDt)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newDt != null) {
|
||||
BitFieldDataType.checkBaseDataType(newDt);
|
||||
int maxBitSize = 8 * newDt.getLength();
|
||||
if (bitfieldDt.getBitSize() > maxBitSize) {
|
||||
throw new InvalidDataTypeException("Replacement datatype too small for bitfield");
|
||||
// Replacement datatype too small for bitfield
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,7 +184,7 @@ abstract class CompositeDB extends DataTypeDB implements CompositeInternal {
|
|||
newDt.addParent(this);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
throw new AssertException("unexpected");
|
||||
throw new AssertException(e); // unexpected
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -19,6 +19,8 @@ import java.io.IOException;
|
|||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import db.DBRecord;
|
||||
import ghidra.docking.settings.*;
|
||||
import ghidra.program.database.DBObjectCache;
|
||||
|
@ -614,4 +616,12 @@ abstract class DataTypeDB extends DatabaseObject implements DataType {
|
|||
return existingDataType.isEquivalent(otherDataType);
|
||||
}
|
||||
|
||||
static String prependComment(String additionalComment, String oldComment) {
|
||||
String comment = additionalComment;
|
||||
if (!StringUtils.isBlank(oldComment)) {
|
||||
comment += "; " + oldComment;
|
||||
}
|
||||
return comment;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -156,6 +156,13 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
|||
private LinkedList<Pair<DataType, DataType>> typesToReplace = new LinkedList<>();
|
||||
private List<DataType> favoritesList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Set of {@link AbstractIntegerDataType} IDs whose removal has been blocked
|
||||
* to allow persistence of defined bitfields.
|
||||
* See {@link #blockDataTypeRemoval(AbstractIntegerDataType)}
|
||||
*/
|
||||
private Set<Long> blockedRemovalsByID;
|
||||
|
||||
// TODO: idsToDataTypeMap may have issue since there could be a one to many mapping
|
||||
// (e.g., type with same UniversalID could be in multiple categories unless specifically
|
||||
// prevented during resolve)
|
||||
|
@ -2299,6 +2306,26 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a {@link AbstractIntegerDataType}, during an invocation of
|
||||
* {@link StructureDB#dataTypeDeleted(DataType)} or {@link UnionDB#dataTypeDeleted(DataType)},
|
||||
* to block final removal of the specified datatype since it is required for persistence of a
|
||||
* defined bitfield. It is required that this be done within the same thread where this manager
|
||||
* has initiated the removal and callbacks.
|
||||
* @param dt integer datatype which should be retained and not deleted
|
||||
*/
|
||||
void blockDataTypeRemoval(AbstractIntegerDataType dt) {
|
||||
long id = getID(dt);
|
||||
if (id == NULL_DATATYPE_ID) {
|
||||
throw new IllegalArgumentException(
|
||||
"Datatype instance is not associated with this manager");
|
||||
}
|
||||
if (blockedRemovalsByID == null) {
|
||||
blockedRemovalsByID = new HashSet<>();
|
||||
}
|
||||
blockedRemovalsByID.add(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given datatype from this manager (assumes the lock has already been acquired).
|
||||
*
|
||||
|
@ -2335,8 +2362,15 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
|||
|
||||
// perform actual database updates (e.g., record removal, change notifications, etc.)
|
||||
for (long id : deletedIds) {
|
||||
if (blockedRemovalsByID != null && blockedRemovalsByID.contains(id)) {
|
||||
DataType dt = getDataType(id);
|
||||
Msg.warn(this, "The datatype '" + dt.getDisplayName() +
|
||||
"' has been retained for use by defined bitfields");
|
||||
continue;
|
||||
}
|
||||
deleteDataType(id);
|
||||
}
|
||||
blockedRemovalsByID = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2367,14 +2401,11 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
|
|||
public boolean remove(DataType dataType, TaskMonitor monitor) {
|
||||
lock.acquire();
|
||||
try {
|
||||
if (contains(dataType)) {
|
||||
return removeInternal(dataType);
|
||||
}
|
||||
return removeInternal(dataType);
|
||||
}
|
||||
finally {
|
||||
lock.release();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -321,7 +321,7 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setArguments(ParameterDefinition[] args) {
|
||||
public void setArguments(ParameterDefinition... args) {
|
||||
lock.acquire();
|
||||
try {
|
||||
checkDeleted();
|
||||
|
@ -413,15 +413,26 @@ class FunctionDefinitionDB extends DataTypeDB implements FunctionDefinition {
|
|||
lock.acquire();
|
||||
try {
|
||||
checkDeleted();
|
||||
boolean changed = false;
|
||||
int n = parameters.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
ParameterDefinitionDB param = parameters.get(i);
|
||||
if (param.getDataType() == dt) {
|
||||
param.setDataType(DataType.DEFAULT);
|
||||
param.doSetDataType(DataType.DEFAULT, false);
|
||||
param.doSetComment(
|
||||
prependComment("Type '" + dt.getDisplayName() + "' was deleted",
|
||||
param.getComment()),
|
||||
false);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (dt == getReturnType()) {
|
||||
setReturnType(DataType.DEFAULT);
|
||||
// NOTE: Not sure how to reflect in a comment
|
||||
doSetReturnType(DataType.DEFAULT, false, false);
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
dataMgr.dataTypeChanged(this, true);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
|
|
|
@ -133,10 +133,16 @@ final class ParameterDefinitionDB implements ParameterDefinition {
|
|||
|
||||
@Override
|
||||
public void setComment(String comment) {
|
||||
doSetComment(comment, true);
|
||||
}
|
||||
|
||||
void doSetComment(String comment, boolean notify) {
|
||||
record.setString(FunctionParameterAdapter.PARAMETER_COMMENT_COL, comment);
|
||||
try {
|
||||
adapter.updateRecord(record);
|
||||
dataMgr.dataTypeChanged(parent, false);
|
||||
if (notify) {
|
||||
dataMgr.dataTypeChanged(parent, false);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
dataMgr.dbError(e);
|
||||
|
|
|
@ -1836,20 +1836,30 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
|||
int n = components.size();
|
||||
for (int i = n - 1; i >= 0; i--) {
|
||||
DataTypeComponentDB dtc = components.get(i);
|
||||
boolean removeBitFieldComponent = false;
|
||||
if (dtc.isBitFieldComponent()) {
|
||||
// Do not allow bitfield to be destroyed
|
||||
// If base type is removed - revert to primitive type
|
||||
BitFieldDataType bitfieldDt = (BitFieldDataType) dtc.getDataType();
|
||||
removeBitFieldComponent = bitfieldDt.getBaseDataType() == dt;
|
||||
if (bitfieldDt.getBaseDataType() == dt) {
|
||||
AbstractIntegerDataType primitiveDt = bitfieldDt.getPrimitiveBaseDataType();
|
||||
dataMgr.blockDataTypeRemoval(primitiveDt);
|
||||
if (primitiveDt != dt && updateBitFieldDataType(dtc, dt, primitiveDt)) {
|
||||
dtc.setComment(
|
||||
prependComment("Type '" + dt.getDisplayName() + "' was deleted",
|
||||
dtc.getComment()));
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removeBitFieldComponent || dtc.getDataType() == dt) {
|
||||
doDelete(i);
|
||||
// for non-packed offsets of remaining components will not change
|
||||
shiftOffsets(i, dtc.getLength() - 1, 0); // ordinals only
|
||||
--numComponents; // may be revised by repack
|
||||
else if (dtc.getDataType() == dt) {
|
||||
setComponentDataType(dtc, BadDataType.dataType, i);
|
||||
dtc.setComment(prependComment("Type '" + dt.getDisplayName() + "' was deleted",
|
||||
dtc.getComment()));
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed && !repack(false, true)) {
|
||||
// repack not needed for non-packed structure - nothing should move
|
||||
if (changed && (!isPackingEnabled() || !repack(false, true))) {
|
||||
dataMgr.dataTypeChanged(this, false);
|
||||
}
|
||||
}
|
||||
|
@ -2344,7 +2354,7 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
|||
checkDeleted();
|
||||
DataType replacementDt = newDt;
|
||||
try {
|
||||
validateDataType(replacementDt);
|
||||
replacementDt = validateDataType(replacementDt); // blocks DEFAULT use for packed
|
||||
replacementDt = resolve(replacementDt);
|
||||
checkAncestry(replacementDt);
|
||||
}
|
||||
|
@ -2355,39 +2365,12 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
|||
|
||||
boolean changed = false;
|
||||
for (int i = components.size() - 1; i >= 0; i--) {
|
||||
|
||||
DataTypeComponentDB comp = components.get(i);
|
||||
|
||||
boolean remove = false;
|
||||
if (comp.isBitFieldComponent()) {
|
||||
try {
|
||||
changed |= updateBitFieldDataType(comp, oldDt, replacementDt);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
Msg.error(this,
|
||||
"Invalid bitfield replacement type " + newDt.getName() +
|
||||
", removing bitfield " + comp.getDataType().getName() + ": " +
|
||||
getPathName());
|
||||
remove = true;
|
||||
}
|
||||
changed |= updateBitFieldDataType(comp, oldDt, replacementDt);
|
||||
}
|
||||
else if (comp.getDataType() == oldDt) {
|
||||
if (replacementDt == DEFAULT && isPackingEnabled()) {
|
||||
Msg.error(this,
|
||||
"Invalid replacement type " + newDt.getName() +
|
||||
", removing component " + comp.getDataType().getName() + ": " +
|
||||
getPathName());
|
||||
remove = true;
|
||||
}
|
||||
else {
|
||||
setComponentDataType(comp, replacementDt, i);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (remove) {
|
||||
// error case - remove component
|
||||
doDelete(i);
|
||||
shiftOffsets(i, comp.getLength() - 1, 0); // ordinals only
|
||||
setComponentDataType(comp, replacementDt, i);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import ghidra.program.database.DBObjectCache;
|
|||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataTypeConflictHandler.ConflictResult;
|
||||
import ghidra.program.model.mem.MemBuffer;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
/**
|
||||
* Database implementation for the Union data type.
|
||||
|
@ -715,20 +714,32 @@ class UnionDB extends CompositeDB implements UnionInternal {
|
|||
boolean changed = false;
|
||||
for (int i = components.size() - 1; i >= 0; i--) { // reverse order
|
||||
DataTypeComponentDB dtc = components.get(i);
|
||||
boolean removeBitFieldComponent = false;
|
||||
if (dtc.isBitFieldComponent()) {
|
||||
|
||||
// Do not allow bitfield to be destroyed
|
||||
// If base type is removed - revert to primitive type
|
||||
BitFieldDataType bitfieldDt = (BitFieldDataType) dtc.getDataType();
|
||||
removeBitFieldComponent = bitfieldDt.getBaseDataType() == dt;
|
||||
if (bitfieldDt.getBaseDataType() == dt) {
|
||||
AbstractIntegerDataType primitiveDt = bitfieldDt.getPrimitiveBaseDataType();
|
||||
dataMgr.blockDataTypeRemoval(primitiveDt);
|
||||
if (primitiveDt != dt && updateBitFieldDataType(dtc, dt, primitiveDt)) {
|
||||
dtc.setComment(
|
||||
prependComment("Type '" + dt.getDisplayName() + "' was deleted",
|
||||
dtc.getComment()));
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removeBitFieldComponent || dtc.getDataType() == dt) {
|
||||
else if (dtc.getDataType() == dt) {
|
||||
dt.removeParent(this);
|
||||
components.remove(i);
|
||||
removeComponentRecord(dtc.getKey());
|
||||
shiftOrdinals(i, -1);
|
||||
dtc.setDataType(BadDataType.dataType); // updates record
|
||||
dataMgr.getSettingsAdapter().removeAllSettingsRecords(dtc.getKey());
|
||||
dtc.setComment(prependComment("Type '" + dt.getDisplayName() + "' was deleted",
|
||||
dtc.getComment()));
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed && !repack(false, true)) {
|
||||
if (changed && (!isPackingEnabled() || !repack(false, true))) {
|
||||
dataMgr.dataTypeChanged(this, false);
|
||||
}
|
||||
}
|
||||
|
@ -821,58 +832,26 @@ class UnionDB extends CompositeDB implements UnionInternal {
|
|||
checkDeleted();
|
||||
DataType replacementDt = newDt;
|
||||
try {
|
||||
validateDataType(replacementDt);
|
||||
if (!(replacementDt instanceof DataTypeDB) ||
|
||||
(replacementDt.getDataTypeManager() != getDataTypeManager())) {
|
||||
replacementDt = resolve(replacementDt);
|
||||
}
|
||||
replacementDt = validateDataType(replacementDt); // blocks DEFAULT use
|
||||
replacementDt = replacementDt.clone(dataMgr);
|
||||
checkAncestry(replacementDt);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// TODO: should we flag bad replacement
|
||||
replacementDt = Undefined1DataType.dataType;
|
||||
}
|
||||
boolean changed = false;
|
||||
for (int i = components.size() - 1; i >= 0; i--) {
|
||||
|
||||
DataTypeComponentDB dtc = components.get(i);
|
||||
|
||||
boolean remove = false;
|
||||
if (dtc.isBitFieldComponent()) {
|
||||
try {
|
||||
changed |= updateBitFieldDataType(dtc, oldDt, replacementDt);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
Msg.error(this,
|
||||
"Invalid bitfield replacement type " + newDt.getName() +
|
||||
", removing bitfield " + dtc.getDataType().getName() + ": " +
|
||||
getPathName());
|
||||
remove = true;
|
||||
}
|
||||
changed |= updateBitFieldDataType(dtc, oldDt, replacementDt);
|
||||
}
|
||||
else if (dtc.getDataType() == oldDt) {
|
||||
if (replacementDt == DEFAULT) {
|
||||
Msg.error(this,
|
||||
"Invalid replacement type " + newDt.getName() +
|
||||
", removing component " + dtc.getDataType().getName() + ": " +
|
||||
getPathName());
|
||||
remove = true;
|
||||
}
|
||||
else {
|
||||
int len = getPreferredComponentLength(newDt, dtc.getLength());
|
||||
dtc.setLength(len, false);
|
||||
oldDt.removeParent(this);
|
||||
dtc.setDataType(replacementDt); // updates record
|
||||
dataMgr.getSettingsAdapter().removeAllSettingsRecords(dtc.getKey());
|
||||
replacementDt.addParent(this);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (remove) {
|
||||
int len = getPreferredComponentLength(newDt, dtc.getLength());
|
||||
dtc.setLength(len, false);
|
||||
oldDt.removeParent(this);
|
||||
components.remove(i);
|
||||
removeComponentRecord(dtc.getKey());
|
||||
shiftOrdinals(i, -1);
|
||||
dtc.setDataType(replacementDt); // updates record
|
||||
dataMgr.getSettingsAdapter().removeAllSettingsRecords(dtc.getKey());
|
||||
replacementDt.addParent(this);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,8 @@ public class BitFieldDataType extends AbstractDataType {
|
|||
* bit size may be reduced based upon the specified base datatype size.
|
||||
* @param bitOffset right shift factor within storage unit when viewed as a big-endian dd
|
||||
* scalar value. Based upon minimal storage bitOffset should be in the range 0 to 7.
|
||||
* @throws InvalidDataTypeException
|
||||
* @throws InvalidDataTypeException if invalid base datatype has been specified or an
|
||||
* invalid bitSize or bitOffset has been specified
|
||||
*/
|
||||
protected BitFieldDataType(DataType baseDataType, int bitSize, int bitOffset)
|
||||
throws InvalidDataTypeException {
|
||||
|
@ -234,8 +235,8 @@ public class BitFieldDataType extends AbstractDataType {
|
|||
public AbstractIntegerDataType getPrimitiveBaseDataType() {
|
||||
// assumes proper enforcement during construction
|
||||
DataType dt = baseDataType;
|
||||
if (baseDataType instanceof TypeDef) {
|
||||
dt = ((TypeDef) baseDataType).getBaseDataType();
|
||||
while (dt instanceof TypeDef typeDef) {
|
||||
dt = typeDef.getBaseDataType();
|
||||
}
|
||||
if (dt instanceof Enum) {
|
||||
// TODO: uncertain if we should use signed or unsigned, although size
|
||||
|
@ -417,8 +418,8 @@ public class BitFieldDataType extends AbstractDataType {
|
|||
return ((Enum) dt).getRepresentation(big, settings, effectiveBitSize);
|
||||
}
|
||||
AbstractIntegerDataType intDT = (AbstractIntegerDataType) dt;
|
||||
if (intDT.getFormatSettingsDefinition().getFormat(
|
||||
settings) == FormatSettingsDefinition.CHAR) {
|
||||
if (intDT.getFormatSettingsDefinition()
|
||||
.getFormat(settings) == FormatSettingsDefinition.CHAR) {
|
||||
if (big.signum() < 0) {
|
||||
big = big.add(BigInteger.valueOf(2).pow(effectiveBitSize));
|
||||
}
|
||||
|
|
|
@ -233,24 +233,23 @@ public abstract class CompositeDataTypeImpl extends GenericDataType implements C
|
|||
* @param oldDt affected datatype which has been removed or replaced
|
||||
* @param newDt replacement datatype
|
||||
* @return true if bitfield component was modified
|
||||
* @throws InvalidDataTypeException if new datatype is not
|
||||
*/
|
||||
protected boolean updateBitFieldDataType(DataTypeComponentImpl bitfieldComponent,
|
||||
DataType oldDt, DataType newDt) throws InvalidDataTypeException {
|
||||
DataType oldDt, DataType newDt) {
|
||||
if (!bitfieldComponent.isBitFieldComponent()) {
|
||||
throw new AssertException("expected bitfield component");
|
||||
}
|
||||
|
||||
BitFieldDataType bitfieldDt = (BitFieldDataType) bitfieldComponent.getDataType();
|
||||
if (bitfieldDt.getBaseDataType() != oldDt) {
|
||||
if (bitfieldDt.getBaseDataType() != oldDt || !BitFieldDataType.isValidBaseDataType(newDt)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newDt != null) {
|
||||
BitFieldDataType.checkBaseDataType(newDt);
|
||||
int maxBitSize = 8 * newDt.getLength();
|
||||
if (bitfieldDt.getBitSize() > maxBitSize) {
|
||||
throw new InvalidDataTypeException("Replacement datatype too small for bitfield");
|
||||
// Replacement datatype too small for bitfield
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +261,7 @@ public abstract class CompositeDataTypeImpl extends GenericDataType implements C
|
|||
newDt.addParent(this);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
throw new AssertException("unexpected");
|
||||
throw new AssertException(e); // unexpected
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -332,6 +332,9 @@ public class DataTypeComponentImpl implements InternalDataTypeComponent, Seriali
|
|||
if (DataTypeComponent.usesZeroLengthComponent(dataType)) {
|
||||
return 0;
|
||||
}
|
||||
if ((dataType instanceof Dynamic dynamic) && dynamic.canSpecifyLength()) {
|
||||
return length;
|
||||
}
|
||||
int dtLength = dataType.getLength();
|
||||
if (length <= 0) {
|
||||
length = dtLength;
|
||||
|
|
|
@ -308,7 +308,14 @@ public interface DataTypeManager {
|
|||
public void removeInvalidatedListener(InvalidatedListener listener);
|
||||
|
||||
/**
|
||||
* Remove the given datatype from this manager
|
||||
* Remove the given datatype from this manager.
|
||||
* <br>
|
||||
* NOTE: Any use of the specified datatype within a {@link FunctionDefinition} will be
|
||||
* converted to the {@link DataType#DEFAULT default 'undefined' datatype}. Any use within
|
||||
* a {@link Structure} or {@link Union} will be converted to the {@link BadDataType} as
|
||||
* a placeholder to retain the component's field name and length (the comment will be prefixed
|
||||
* with a message indicating the remval of the old datatype.
|
||||
*
|
||||
* @param dataType the dataType to be removed
|
||||
* @param monitor the task monitor
|
||||
* @return true if the data type existed and was removed
|
||||
|
|
|
@ -29,7 +29,7 @@ public interface FunctionDefinition extends DataType, FunctionSignature {
|
|||
* Set the arguments to this function.
|
||||
* @param args array of parameter definitions to be used as arguments to this function
|
||||
*/
|
||||
public void setArguments(ParameterDefinition[] args);
|
||||
public void setArguments(ParameterDefinition... args);
|
||||
|
||||
/**
|
||||
* Set the return data type for this function
|
||||
|
|
|
@ -141,7 +141,7 @@ public class FunctionDefinitionDataType extends GenericDataType implements Funct
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setArguments(ParameterDefinition[] args) {
|
||||
public void setArguments(ParameterDefinition... args) {
|
||||
params = new ParameterDefinition[args.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
DataType dt = args[i].getDataType();
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.util.*;
|
|||
import ghidra.docking.settings.Settings;
|
||||
import ghidra.program.model.data.AlignedStructurePacker.StructurePackResult;
|
||||
import ghidra.program.model.mem.MemBuffer;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.UniversalID;
|
||||
import ghidra.util.exception.AssertException;
|
||||
|
||||
|
@ -1296,80 +1295,50 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
|||
int n = components.size();
|
||||
for (int i = n - 1; i >= 0; i--) {
|
||||
DataTypeComponentImpl dtc = components.get(i);
|
||||
boolean removeBitFieldComponent = false;
|
||||
if (dtc.isBitFieldComponent()) {
|
||||
// Do not allow bitfield to be destroyed
|
||||
// If base type is removed - revert to primitive type
|
||||
BitFieldDataType bitfieldDt = (BitFieldDataType) dtc.getDataType();
|
||||
removeBitFieldComponent = bitfieldDt.getBaseDataType() == dt;
|
||||
if (bitfieldDt.getBaseDataType() == dt &&
|
||||
updateBitFieldDataType(dtc, dt, bitfieldDt.getPrimitiveBaseDataType())) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (removeBitFieldComponent || dtc.getDataType() == dt) {
|
||||
dt.removeParent(this);
|
||||
// FIXME: Consider replacing with undefined type instead of removing (don't remove bitfield)
|
||||
components.remove(i);
|
||||
shiftOffsets(i, dtc.getLength() - 1, 0);
|
||||
--numComponents; // may be revised by repack
|
||||
else if (dtc.getDataType() == dt) {
|
||||
setComponentDataType(dtc, BadDataType.dataType, i);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
// Should be no impact for non-packed
|
||||
if (changed && !isPackingEnabled()) {
|
||||
repack(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dataTypeReplaced(DataType oldDt, DataType replacementDt)
|
||||
throws IllegalArgumentException {
|
||||
DataType newDt = replacementDt;
|
||||
public void dataTypeReplaced(DataType oldDt, DataType newDt) throws IllegalArgumentException {
|
||||
DataType replacementDt = newDt;
|
||||
try {
|
||||
validateDataType(replacementDt);
|
||||
replacementDt = validateDataType(replacementDt); // blocks DEFAULT use for packed
|
||||
replacementDt = replacementDt.clone(dataMgr);
|
||||
checkAncestry(replacementDt);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// TODO: should we use Undefined1 instead to avoid cases where
|
||||
// DEFAULT datatype can not be used (bitfield, aligned structure, etc.)
|
||||
// TODO: failing silently is rather hidden
|
||||
replacementDt = DataType.DEFAULT;
|
||||
// Handle bad replacement with use of undefined component
|
||||
replacementDt = isPackingEnabled() ? Undefined1DataType.dataType : DataType.DEFAULT;
|
||||
}
|
||||
|
||||
boolean changed = false;
|
||||
for (int i = components.size() - 1; i >= 0; i--) {
|
||||
|
||||
DataTypeComponentImpl comp = components.get(i);
|
||||
|
||||
boolean remove = false;
|
||||
if (comp.isBitFieldComponent()) {
|
||||
try {
|
||||
changed |= updateBitFieldDataType(comp, oldDt, replacementDt);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
Msg.error(this,
|
||||
"Invalid bitfield replacement type " + newDt.getName() +
|
||||
", removing bitfield " + comp.getDataType().getName() + ": " +
|
||||
getPathName());
|
||||
remove = true;
|
||||
}
|
||||
changed |= updateBitFieldDataType(comp, oldDt, replacementDt);
|
||||
}
|
||||
else if (comp.getDataType() == oldDt) {
|
||||
if (replacementDt == DEFAULT && isPackingEnabled()) {
|
||||
Msg.error(this,
|
||||
"Invalid replacement type " + newDt.getName() + ", removing component " +
|
||||
comp.getDataType().getName() + ": " + getPathName());
|
||||
remove = true;
|
||||
}
|
||||
else {
|
||||
setComponentDataType(comp, replacementDt, i);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (remove) {
|
||||
// error case - remove component
|
||||
oldDt.removeParent(this);
|
||||
components.remove(i);
|
||||
shiftOffsets(i, comp.getLength() - 1, 0); // ordinals only
|
||||
setComponentDataType(comp, replacementDt, i);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
repack(false);
|
||||
notifySizeChanged(); // also handles alignment change
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.util.*;
|
|||
|
||||
import ghidra.docking.settings.Settings;
|
||||
import ghidra.program.model.mem.MemBuffer;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.UniversalID;
|
||||
|
||||
/**
|
||||
|
@ -505,57 +504,26 @@ public class UnionDataType extends CompositeDataTypeImpl implements UnionInterna
|
|||
public void dataTypeReplaced(DataType oldDt, DataType newDt) throws IllegalArgumentException {
|
||||
DataType replacementDt = newDt;
|
||||
try {
|
||||
validateDataType(replacementDt);
|
||||
if (replacementDt.getDataTypeManager() != dataMgr) {
|
||||
replacementDt = replacementDt.clone(dataMgr);
|
||||
}
|
||||
replacementDt = validateDataType(replacementDt); // blocks DEFAULT use
|
||||
replacementDt = replacementDt.clone(dataMgr);
|
||||
checkAncestry(replacementDt);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// TODO: should we use Undefined instead since we do not support
|
||||
// DEFAULT in Unions
|
||||
replacementDt = DataType.DEFAULT;
|
||||
replacementDt = Undefined1DataType.dataType;
|
||||
}
|
||||
boolean changed = false;
|
||||
for (int i = components.size() - 1; i >= 0; i--) {
|
||||
|
||||
DataTypeComponentImpl dtc = components.get(i);
|
||||
|
||||
boolean remove = false;
|
||||
if (dtc.isBitFieldComponent()) {
|
||||
try {
|
||||
changed |= updateBitFieldDataType(dtc, oldDt, replacementDt);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
Msg.error(this,
|
||||
"Invalid bitfield replacement type " + newDt.getName() +
|
||||
", removing bitfield " + dtc.getDataType().getName() + ": " +
|
||||
getPathName());
|
||||
remove = true;
|
||||
}
|
||||
changed |= updateBitFieldDataType(dtc, oldDt, replacementDt);
|
||||
}
|
||||
else if (dtc.getDataType() == oldDt) {
|
||||
if (replacementDt == DEFAULT) {
|
||||
Msg.error(this,
|
||||
"Invalid replacement type " + newDt.getName() + ", removing component " +
|
||||
dtc.getDataType().getName() + ": " + getPathName());
|
||||
remove = true;
|
||||
}
|
||||
else {
|
||||
int len = getPreferredComponentLength(newDt, dtc.getLength());
|
||||
oldDt.removeParent(this);
|
||||
dtc.setLength(len);
|
||||
dtc.setDataType(replacementDt);
|
||||
dtc.invalidateSettings();
|
||||
replacementDt.addParent(this);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (remove) {
|
||||
// error case - remove component
|
||||
int len = getPreferredComponentLength(newDt, dtc.getLength());
|
||||
oldDt.removeParent(this);
|
||||
components.remove(i);
|
||||
shiftOrdinals(i, -1);
|
||||
dtc.setLength(len);
|
||||
dtc.setDataType(replacementDt);
|
||||
dtc.invalidateSettings();
|
||||
replacementDt.addParent(this);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
@ -570,19 +538,22 @@ public class UnionDataType extends CompositeDataTypeImpl implements UnionInterna
|
|||
boolean changed = false;
|
||||
for (int i = components.size() - 1; i >= 0; i--) { // reverse order
|
||||
DataTypeComponentImpl dtc = components.get(i);
|
||||
boolean removeBitFieldComponent = false;
|
||||
if (dtc.isBitFieldComponent()) {
|
||||
// Do not allow bitfield to be destroyed
|
||||
// If base type is removed - revert to primitive type
|
||||
BitFieldDataType bitfieldDt = (BitFieldDataType) dtc.getDataType();
|
||||
removeBitFieldComponent = bitfieldDt.getBaseDataType() == dt;
|
||||
if (bitfieldDt.getBaseDataType() == dt &&
|
||||
updateBitFieldDataType(dtc, dt, bitfieldDt.getPrimitiveBaseDataType())) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (removeBitFieldComponent || dtc.getDataType() == dt) {
|
||||
else if (dtc.getDataType() == dt) {
|
||||
dt.removeParent(this);
|
||||
components.remove(i);
|
||||
shiftOrdinals(i, -1);
|
||||
dtc.setDataType(BadDataType.dataType); // updates record
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed && !repack(true) && isPackingEnabled()) {
|
||||
if (changed && isPackingEnabled() && !repack(true)) {
|
||||
// NOTE: Must assume alignment change since we are unable to determine
|
||||
// without stored alignment
|
||||
notifyAlignmentChanged();
|
||||
|
|
|
@ -1153,13 +1153,34 @@ public class StructureDBTest extends AbstractGenericTest {
|
|||
assertEquals(8, struct.getLength());
|
||||
|
||||
struct.add(new ArrayDataType(IntegerDataType.dataType, 0, -1), "flex", "FlexComment");
|
||||
assertEquals(5, struct.getNumComponents());
|
||||
assertEquals(8, struct.getLength());
|
||||
|
||||
//@formatter:off
|
||||
CompositeTestUtils.assertExpectedComposite(this, "/Test\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Test {\n" +
|
||||
" 0 byte 1 field1 \"Comment1\"\n" +
|
||||
" 1 word 2 \"Comment2\"\n" +
|
||||
" 3 dword 4 field3 \"\"\n" +
|
||||
" 7 byte 1 field4 \"Comment4\"\n" +
|
||||
" 8 int[0] 0 flex \"FlexComment\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 1", struct);
|
||||
//@formatter:on
|
||||
|
||||
dataMgr.remove(dataMgr.resolve(IntegerDataType.dataType, null), TaskMonitor.DUMMY);
|
||||
|
||||
assertEquals(4, struct.getNumComponents());
|
||||
assertEquals(8, struct.getLength());
|
||||
//@formatter:off
|
||||
CompositeTestUtils.assertExpectedComposite(this, "/Test\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Test {\n" +
|
||||
" 0 byte 1 field1 \"Comment1\"\n" +
|
||||
" 1 word 2 \"Comment2\"\n" +
|
||||
" 3 dword 4 field3 \"\"\n" +
|
||||
" 7 byte 1 field4 \"Comment4\"\n" +
|
||||
" 8 -BAD- 0 flex \"Type 'int[0]' was deleted; FlexComment\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 1", struct);
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1197,9 +1218,9 @@ public class StructureDBTest extends AbstractGenericTest {
|
|||
" 1 word 2 \"Comment2\"\n" +
|
||||
" 3 dword 4 field3 \"\"\n" +
|
||||
" 7 byte 1 field4 \"Comment4\"\n" +
|
||||
// " 8 undefined 1 \"\"\n" +
|
||||
// " 9 undefined 1 \"\"\n" +
|
||||
// " 10 undefined 1 \"\"\n" +
|
||||
" 8 int:4(0) 1 MyBit1 \"Type 'Foo' was deleted; bitComment\"\n" +
|
||||
" 9 int:3(0) 1 MyBit2 \"Type 'Foo' was deleted; bitComment\"\n" +
|
||||
" 10 int:2(0) 1 MyBit3 \"Type 'Foo' was deleted; bitComment\"\n" +
|
||||
"}\n" +
|
||||
"Length: 11 Alignment: 1", struct);
|
||||
//@formatter:on
|
||||
|
@ -1807,14 +1828,33 @@ public class StructureDBTest extends AbstractGenericTest {
|
|||
DataType dt = struct.getDataTypeManager().getDataType(struct.getCategoryPath(), "test1");
|
||||
assertNotNull(dt);
|
||||
|
||||
DataTypeComponent[] dtc = struct.getComponents();
|
||||
assertEquals(5, dtc.length);
|
||||
//@formatter:off
|
||||
CompositeTestUtils.assertExpectedComposite(this, "/Test\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Test {\n" +
|
||||
" 0 byte 1 field1 \"Comment1\"\n" +
|
||||
" 1 word 2 \"Comment2\"\n" +
|
||||
" 3 dword 4 field3 \"\"\n" +
|
||||
" 7 byte 1 field4 \"Comment4\"\n" +
|
||||
" 8 test1 5 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 13 Alignment: 1", struct);
|
||||
//@formatter:on
|
||||
|
||||
dt.getDataTypeManager().remove(dt, new TaskMonitorAdapter());
|
||||
dtc = struct.getComponents();
|
||||
assertEquals(9, dtc.length);
|
||||
|
||||
assertEquals(9, struct.getNumComponents());
|
||||
//@formatter:off
|
||||
CompositeTestUtils.assertExpectedComposite(this, "/Test\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Test {\n" +
|
||||
" 0 byte 1 field1 \"Comment1\"\n" +
|
||||
" 1 word 2 \"Comment2\"\n" +
|
||||
" 3 dword 4 field3 \"\"\n" +
|
||||
" 7 byte 1 field4 \"Comment4\"\n" +
|
||||
" 8 -BAD- 5 \"Type 'test1' was deleted\"\n" +
|
||||
"}\n" +
|
||||
"Length: 13 Alignment: 1", struct);
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -280,6 +280,8 @@ public class UnionDBTest extends AbstractGenericTest {
|
|||
"Union TestUnion {\n" +
|
||||
" 0 byte 1 field1 \"Comment1\"\n" +
|
||||
" 0 word 2 \"Comment2\"\n" +
|
||||
" 0 int:4(0) 1 bf1 \"Type 'Foo' was deleted; bf1Comment\"\n" +
|
||||
" 0 int:4(0) 1 bf2 \"Type 'Foo' was deleted; bf2Comment\"\n" +
|
||||
" 0 dword 4 field3 \"\"\n" +
|
||||
" 0 byte 1 field4 \"Comment4\"\n" +
|
||||
"}\n" +
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue