diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionSignatureCmd.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionSignatureCmd.java index a3af2168cc..2eee3110d0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionSignatureCmd.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/ApplyFunctionSignatureCmd.java @@ -76,10 +76,6 @@ public class ApplyFunctionSignatureCmd extends BackgroundCommand { this.setName = setName; } - /** - * - * @see ghidra.framework.cmd.BackgroundCommand#applyTo(ghidra.framework.model.DomainObject, ghidra.util.task.TaskMonitor) - */ @Override public boolean applyTo(DomainObject obj, TaskMonitor monitor) { program = (Program) obj; @@ -111,10 +107,10 @@ public class ApplyFunctionSignatureCmd extends BackgroundCommand { /** * Sets a function's signature in the program. - * @param program The program containing the function. * @param func the function * @param signature the signature to apply - * @param preserveCallingConvention if true, the functions calling convention will not be modified + * @param preserveCallingConvention if true, the functions calling convention will not be + * modified * @param forceName force the name of the signature onto the function * normally the name is only set on default function names (not user-defined). * @param source the source of this function signature @@ -224,7 +220,7 @@ public class ApplyFunctionSignatureCmd extends BackgroundCommand { PrototypeModel convention = function.getCallingConvention(); if (convention == null || !preserveCallingConvention) { convention = preferredModel; -// NOTE: This has been disable since it can cause imported signature information to be +// NOTE: This has been disable since it can cause imported signature information to be // ignored and overwritten by subsequent analysis // if (convention == null && compilerSpec.getCallingConventions().length > 1) { // // use default source for signature if convention is really unknown so that we @@ -337,12 +333,13 @@ public class ApplyFunctionSignatureCmd extends BackgroundCommand { * The C language assumes array datatypes are passed simply as pointers (by reference) even though * other datatypes are passed by value. This routine converts the datatype to the appropriate pointer * in situations where we need to get at the exact type being passed by "value" - * @param dt - * @return + * @param dt the type + * @param dtm the data type manager + * @return the updated type */ - public static DataType settleCDataType(DataType dt, DataTypeManager dtm) { + private static DataType settleCDataType(DataType dt, DataTypeManager dtm) { if (dt == null) { - return dt; + return null; } DataType baseType = dt; if (baseType instanceof TypedefDataType) { diff --git a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RetypeFieldAction.java b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RetypeFieldAction.java index 4ebce09bde..9c9df34fbd 100644 --- a/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RetypeFieldAction.java +++ b/Ghidra/Features/Decompiler/src/main/java/ghidra/app/plugin/core/decompile/actions/RetypeFieldAction.java @@ -25,7 +25,6 @@ import ghidra.app.decompiler.ClangFieldToken; import ghidra.app.decompiler.ClangToken; import ghidra.app.plugin.core.decompile.DecompilerActionContext; import ghidra.app.util.HelpTopics; -import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.data.*; import ghidra.program.model.listing.Function; import ghidra.program.model.listing.Program; @@ -68,68 +67,69 @@ public class RetypeFieldAction extends AbstractDecompilerAction { @Override protected void decompilerActionPerformed(DecompilerActionContext context) { - Program program = context.getProgram(); - PluginTool tool = context.getTool(); + ClangToken tokenAtCursor = context.getTokenAtCursor(); - DataTypeManager dataTypeManager = program.getDataTypeManager(); - Structure struct = getStructDataType(tokenAtCursor); - int offset = ((ClangFieldToken) tokenAtCursor).getOffset(); if (struct == null) { - Msg.showError(this, tool.getToolFrame(), "Retype Failed", - "Failed to re-type structure"); - return; - } - if (offset < 0 || offset >= struct.getLength()) { - Msg.showError(this, tool.getToolFrame(), "Retype Failed", - "Failed to re-type structure field at offset " + offset + ": " + struct.getName()); + Msg.showError(this, null, "Retype Failed", "Failed to retype structure field"); return; } - // Get original component and datatype - structure may be packed so an offset which corresponds - // to padding byte may return null + int offset = ((ClangFieldToken) tokenAtCursor).getOffset(); + if (offset < 0 || offset >= struct.getLength()) { + Msg.showError(this, null, "Retype Failed", + "Failed to retype structure field at offset " + offset + ": " + struct.getName()); + return; + } + + // get original component and datatype - structure may be packed so an offset which + // corresponds to padding byte may return null DataTypeComponent comp = struct.getComponentContaining(offset); if (comp != null && comp.getOffset() != offset) { - Msg.showError(this, tool.getToolFrame(), "Retype Failed", - "Retype offset does not correspond to start of component"); + Msg.showError(this, null, "Retype Failed", + "Retype offset does not correspond to start of field"); return; } - DataType originalDataType = comp != null ? comp.getDataType() : DataType.DEFAULT; - if (originalDataType instanceof BitFieldDataType) { - Msg.showError(this, tool.getToolFrame(), "Retype Failed", + + DataType originalType = comp != null ? comp.getDataType() : DataType.DEFAULT; + if (originalType instanceof BitFieldDataType) { + Msg.showError(this, null, "Retype Failed", "Retype of defind bit-field is not supported."); return; } - DataType dataType = chooseDataType(tool, program, originalDataType); - if (dataType == null || dataType.isEquivalent(originalDataType)) { + Program program = context.getProgram(); + DataType newType = chooseDataType(context.getTool(), program, originalType); + if (newType == null || newType.isEquivalent(originalType)) { return; // cancelled } // check for permitted datatype - if (dataType instanceof FactoryDataType || dataType.getLength() <= 0) { - Msg.showError(this, tool.getToolFrame(), "Retype Failed", - "Retype field with \"" + dataType.getName() + "\" data type is not allowed."); + if (newType instanceof FactoryDataType || newType.getLength() <= 0) { + Msg.showError(this, null, "Retype Failed", + "Failed to retype structure field '" + newType.getName() + + "' - data type is not allowed."); + return; } + replaceType(program, struct, offset, comp, originalType, newType); + } + + private void replaceType(Program program, Structure struct, int offset, DataTypeComponent comp, + DataType originalType, DataType newType) { + int transaction = program.startTransaction("Retype Structure Field"); try { - dataType = dataTypeManager.resolve(dataType, null); - int newDtLength = dataType.getLength(); - if (DataTypeComponent.usesZeroLengthComponent(dataType)) { - Msg.showError(this, tool.getToolFrame(), "Retype Failed", "Retype field with \"" + - dataType.getName() + "\" zero-length component is not allowed."); - } - - if (originalDataType != DataType.DEFAULT && - newDtLength == originalDataType.getLength()) { - // Perform simple 1-for-1 component replacement - this allows to avoid unpack in some cases - assume comp is not null - struct.replace(comp.getOrdinal(), dataType, -1); + DataTypeManager dtm = program.getDataTypeManager(); + newType = dtm.resolve(newType, null); + int newDtLength = newType.getLength(); + if (DataTypeComponent.usesZeroLengthComponent(newType)) { + Msg.showError(this, null, "Retype Failed", "Failed to retype structure field '" + + newType.getName() + "' - zero-length component is not allowed."); return; } - // check for datatype fit String fieldName = null; String comment = null; int nextOffset; @@ -141,47 +141,76 @@ public class RetypeFieldAction extends AbstractDecompilerAction { comment = comp.getComment(); nextOffset = comp.getEndOffset() + 1; } + + // we cannot replace a default type, since it is not a real data type + if (originalType != DataType.DEFAULT && + newDtLength == originalType.getLength()) { + // Perform simple 1-for-1 component replacement. This allows to avoid unpack in + // some cases. Assume component is not null since we have a non-default type. + struct.replace(comp.getOrdinal(), newType, -1, fieldName, comment); + return; + } + + // check for datatype fit int available = nextOffset - offset; if (newDtLength > available) { DataTypeComponent nextComp = struct.getDefinedComponentAtOrAfterOffset(nextOffset); int endOffset = nextComp == null ? struct.getLength() : nextComp.getOffset(); available += endOffset - nextOffset; if (newDtLength > available) { - Msg.showError(this, tool.getToolFrame(), "Retype Failed", - "Failed to re-type structure '" + struct.getName() + - "': Datatype will not fit"); + Msg.showError(this, null, "Retype Failed", + "Failed to retype structure field in '" + struct.getName() + + "' - datatype will not fit"); return; } } - if (struct.isPackingEnabled() && !isAlignmentMaintained(comp, dataType, offset)) { - int choice = OptionDialog.showOptionDialogWithCancelAsDefaultButton(null, - "Disable Structure Packing", - "Containing structure currently has packing enabled. Packing will be disabled if you continue.", - "Continue", OptionDialog.WARNING_MESSAGE); - if (choice != OptionDialog.OPTION_ONE) { - return; // cancelled - } - // alignment is maintained for struct since we do not know the extent of the impact if we change it - int alignment = struct.getAlignment(); - struct.setPackingEnabled(false); - struct.setExplicitMinimumAlignment(alignment); // preserve previously computed alignment + if (!verifyPacking(struct, offset, comp, newType)) { + return; } - // The replaceAtOffset will only replace component containing offset plus any subsequent DEFAULT - // components available. Space check is performed prior to any clearing. Zero-length components - // at offset will be ignored. - struct.replaceAtOffset(offset, dataType, -1, fieldName, comment); + // The replaceAtOffset will only replace component containing offset plus any + // subsequent DEFAULT components available. Space check is performed prior to any + // clearing. Zero-length components at offset will be ignored. + struct.replaceAtOffset(offset, newType, -1, fieldName, comment); } catch (IllegalArgumentException e) { - Msg.showError(this, tool.getToolFrame(), "Retype Failed", - "Failed to re-type structure: " + e.getMessage()); + Msg.showError(this, null, "Retype Failed", + "Failed to retype structure field in '" + struct.getName() + "':" + e.getMessage(), + e); } finally { program.endTransaction(transaction, true); } } + private boolean verifyPacking(Structure struct, int offset, DataTypeComponent comp, + DataType dataType) { + + if (!struct.isPackingEnabled()) { + return true; + } + + if (isAlignmentMaintained(comp, dataType, offset)) { + return true; + } + + int choice = OptionDialog.showOptionDialogWithCancelAsDefaultButton(null, + "Disable Structure Packing", + "Containing structure currently has packing enabled. Packing will be " + + "disabled if you continue.", + "Continue", OptionDialog.WARNING_MESSAGE); + if (choice != OptionDialog.OPTION_ONE) { + return false; // cancelled + } + + // alignment is maintained for struct since we do not know the impact if we change it + int alignment = struct.getAlignment(); + struct.setPackingEnabled(false); + struct.setExplicitMinimumAlignment(alignment); // preserve previous alignment + return true; + } + private boolean isAlignmentMaintained(DataTypeComponent comp, DataType dataType, int offset) { if (comp == null) { return false; diff --git a/Ghidra/Features/MicrosoftDemangler/src/test/java/ghidra/app/util/demangler/microsoft/MicrosoftDemanglerTest.java b/Ghidra/Features/MicrosoftDemangler/src/test/java/ghidra/app/util/demangler/microsoft/MicrosoftDemanglerTest.java index 023233c13c..82432229f8 100644 --- a/Ghidra/Features/MicrosoftDemangler/src/test/java/ghidra/app/util/demangler/microsoft/MicrosoftDemanglerTest.java +++ b/Ghidra/Features/MicrosoftDemangler/src/test/java/ghidra/app/util/demangler/microsoft/MicrosoftDemanglerTest.java @@ -24,6 +24,7 @@ import generic.test.AbstractGenericTest; import ghidra.app.util.demangler.*; import ghidra.program.database.ProgramDB; import ghidra.program.model.address.Address; +import ghidra.program.model.listing.*; import ghidra.program.model.symbol.SourceType; import ghidra.program.model.symbol.SymbolTable; import ghidra.test.ToyProgramBuilder; @@ -40,6 +41,31 @@ public class MicrosoftDemanglerTest extends AbstractGenericTest { program = builder.getProgram(); } + @Test + public void testUnsignedShortParameter() throws Exception { + + String mangled = "?InvokeHelperV@COleDispatchDriver@@QAEXJGGPAXPBEPAD@Z"; + + MicrosoftDemangler demangler = new MicrosoftDemangler(); + DemangledObject demangledObject = demangler.demangle(mangled); + + int txID = program.startTransaction("Test"); + + SymbolTable st = program.getSymbolTable(); + st.createLabel(addr("01001000"), mangled, SourceType.ANALYSIS); + + DemanglerOptions options = new DemanglerOptions(); + demangledObject.applyTo(program, addr("01001000"), options, TaskMonitor.DUMMY); + program.endTransaction(txID, true); + + FunctionManager fm = program.getFunctionManager(); + Function function = fm.getFunctionAt(addr("01001000")); + Parameter[] parameters = function.getParameters(); + + // this was broken at one point, returning 'unsigned_short' + assertEquals("ushort", parameters[2].getDataType().getName()); + } + @Test public void testArrayVariable() throws Exception { // NullPointerException String mangled = "?Te@NS1@BobsStuff@@0QAY0BAA@$$CBIA"; @@ -72,9 +98,8 @@ public class MicrosoftDemanglerTest extends AbstractGenericTest { String mangled = "??_R0?AVCBob@@@8~"; MicrosoftDemangler demangler = new MicrosoftDemangler(); - DemangledObject demangledObj = null; try { - demangledObj = demangler.demangle(mangled); + demangler.demangle(mangled); } catch (DemangledException e) { // Expected @@ -88,9 +113,8 @@ public class MicrosoftDemanglerTest extends AbstractGenericTest { String mangled = "?BobsStuffIO@344GPAUHINSTANCE__@@U_COMMPROP@@*E"; MicrosoftDemangler demangler = new MicrosoftDemangler(); - DemangledObject demangledObj = null; try { - demangledObj = demangler.demangle(mangled); + demangler.demangle(mangled); } catch (DemangledException e) { // Expected @@ -104,9 +128,8 @@ public class MicrosoftDemanglerTest extends AbstractGenericTest { String mangled = "?BobsStuffIO@344GPAUHINSTANCE__@@U_COMMPROP@@-W"; MicrosoftDemangler demangler = new MicrosoftDemangler(); - DemangledObject demangledObj = null; try { - demangledObj = demangler.demangle(mangled); + demangler.demangle(mangled); } catch (DemangledException e) { // Expected @@ -120,9 +143,8 @@ public class MicrosoftDemanglerTest extends AbstractGenericTest { String mangled = "?BobsStuffIO@344GPAUHINSTANCE__@@U_COMMPROP@@?W"; MicrosoftDemangler demangler = new MicrosoftDemangler(); - DemangledObject demangledObj = null; try { - demangledObj = demangler.demangle(mangled); + demangler.demangle(mangled); } catch (DemangledException e) { // Expected @@ -136,9 +158,8 @@ public class MicrosoftDemanglerTest extends AbstractGenericTest { String mangled = "?BobsStuffIO@344GPAUHINSTANCE__@@U_COMMPROP@@~W"; MicrosoftDemangler demangler = new MicrosoftDemangler(); - DemangledObject demangledObj = null; try { - demangledObj = demangler.demangle(mangled); + demangler.demangle(mangled); } catch (DemangledException e) { // Expected @@ -152,9 +173,8 @@ public class MicrosoftDemanglerTest extends AbstractGenericTest { String mangled = "?BobsStuffIO@344GPAUHINSTANCE__@@U_COMMPROP@@%W"; MicrosoftDemangler demangler = new MicrosoftDemangler(); - DemangledObject demangledObj = null; try { - demangledObj = demangler.demangle(mangled); + demangler.demangle(mangled); } catch (DemangledException e) { // Expected @@ -168,9 +188,8 @@ public class MicrosoftDemanglerTest extends AbstractGenericTest { String mangled = "?BobsStuffIO@344GPAUHINSTANCE__@@U_COMMPROP@@`W"; MicrosoftDemangler demangler = new MicrosoftDemangler(); - DemangledObject demangledObj = null; try { - demangledObj = demangler.demangle(mangled); + demangler.demangle(mangled); } catch (DemangledException e) { // Expected @@ -184,9 +203,8 @@ public class MicrosoftDemanglerTest extends AbstractGenericTest { String mangled = "?BobsStuffIO@344GPAUHINSTANCE__@@U_COMMPROP@@+W"; MicrosoftDemangler demangler = new MicrosoftDemangler(); - DemangledObject demangledObj = null; try { - demangledObj = demangler.demangle(mangled); + demangler.demangle(mangled); } catch (DemangledException e) { // Expected @@ -200,9 +218,8 @@ public class MicrosoftDemanglerTest extends AbstractGenericTest { String mangled = "?BobsStuffIO@344GPAUHINSTANCE__@@U_COMMPROP@@/W"; MicrosoftDemangler demangler = new MicrosoftDemangler(); - DemangledObject demangledObj = null; try { - demangledObj = demangler.demangle(mangled); + demangler.demangle(mangled); } catch (DemangledException e) { // Expected diff --git a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMangGhidra.java b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMangGhidra.java index f78a7bbf10..2dd5553423 100644 --- a/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMangGhidra.java +++ b/Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/MDMangGhidra.java @@ -839,10 +839,14 @@ public class MDMangGhidra extends MDMang { */ private String getDataTypeName(MDDataType dataType) { String name = dataType.getName(); - if (name.isBlank()) { - return dataType.toString(); + if (!name.isBlank()) { + return name; } - return name; + name = dataType.getTypeName(); + if (!name.isBlank()) { + return name; + } + return dataType.toString(); } } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/BackgroundCommand.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/BackgroundCommand.java index 43044f6f9c..c5390ab589 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/BackgroundCommand.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/cmd/BackgroundCommand.java @@ -17,20 +17,15 @@ package ghidra.framework.cmd; import ghidra.framework.model.DomainObject; import ghidra.util.task.TaskMonitor; -import ghidra.util.task.TaskMonitorAdapter; /** - * Abstract command that will be run in a thread (in the background) - * other than the AWT(GUI) thread. Use this to apply a long running - * command that is interruptable. - * - * The monitor allows the command to display status information as it - * executes. - * - * This allows commands to make changes in the background so that the - * GUI is not frozen and the user can still interact with the GUI. + * Abstract command that will be run in a thread (in the background) other than the AWT(GUI) + * thread. Use this to apply a long running command that is cancellable. * + *
The monitor allows the command to display status information as it executes. * + *
This allows commands to make changes in the background so that the GUI is not frozen and the
+ * user can still interact with the GUI.
*/
public abstract class BackgroundCommand implements Command {
@@ -51,22 +46,17 @@ public abstract class BackgroundCommand implements Command {
this.isModal = isModal;
}
- /*
- * @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
- */
@Override
public final boolean applyTo(DomainObject obj) {
- return applyTo(obj, TaskMonitorAdapter.DUMMY_MONITOR);
+ return applyTo(obj, TaskMonitor.DUMMY);
}
/**
- * Method called when this command is to apply changes to the
- * given domain object. A monitor is provided to display status
- * information about the command as it executes in the background.
+ * Method called when this command is to apply changes to the given domain object. A monitor
+ * is provided to display status information about the command as it executes in the background.
*
* @param obj domain object that will be affected by the command
* @param monitor monitor to show progress of the command
- *
* @return true if the command applied successfully
*/
public abstract boolean applyTo(DomainObject obj, TaskMonitor monitor);
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/PcodeEmit.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/PcodeEmit.java
index 5eae12a060..9c0a7f29c8 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/PcodeEmit.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/processors/sleigh/PcodeEmit.java
@@ -773,7 +773,7 @@ public abstract class PcodeEmit {
}
}
for (int i = 0; i < isize; ++i) {
- VarnodeData v = in[0];
+ VarnodeData v = in[i];
if (v.space.equals(overlayspace)) {
v.space = ((OverlayAddressSpace) v.space).getOverlayedSpace();
}
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/EnumDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/EnumDB.java
index 4c49233f74..66bbfc2333 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/EnumDB.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/EnumDB.java
@@ -545,7 +545,7 @@ class EnumDB extends DataTypeDB implements Enum {
if (subValue != 0) {
String part = getName(subValue);
if (part == null) {
- part = getStringForNoMatchingValue(subValue);
+ part = Long.toHexString(subValue).toUpperCase() + 'h';
}
if (buf.length() != 0) {
buf.append(" | ");
@@ -563,19 +563,6 @@ class EnumDB extends DataTypeDB implements Enum {
return bitGroups;
}
- private String getStringForNoMatchingValue(long value) {
- String valueName;
- String valueStr;
- if (value < 0 || value >= 32) {
- valueStr = "0x" + Long.toHexString(value);
- }
- else {
- valueStr = Long.toString(value);
- }
- valueName = "" + valueStr;
- return valueName;
- }
-
@Override
public boolean isEquivalent(DataType dt) {
if (dt == this) {
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/EnumDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/EnumDataType.java
index decf798263..a02e8997a7 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/EnumDataType.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/EnumDataType.java
@@ -342,7 +342,7 @@ public class EnumDataType extends GenericDataType implements Enum {
if (subValue != 0) {
String part = getName(subValue);
if (part == null) {
- part = getStringForNoMatchingValue(subValue);
+ part = Long.toHexString(subValue).toUpperCase() + 'h';
}
if (buf.length() != 0) {
buf.append(" | ");
@@ -360,19 +360,6 @@ public class EnumDataType extends GenericDataType implements Enum {
return bitGroups;
}
- private String getStringForNoMatchingValue(long value) {
- String valueName;
- String valueStr;
- if (value < 0 || value >= 32) {
- valueStr = "0x" + Long.toHexString(value);
- }
- else {
- valueStr = Long.toString(value);
- }
- valueName = "" + valueStr;
- return valueName;
- }
-
@Override
public boolean isEquivalent(DataType dt) {
if (dt == this) {
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/EnumValuePartitioner.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/EnumValuePartitioner.java
index afb9e831a9..d9158bb8ec 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/EnumValuePartitioner.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/EnumValuePartitioner.java
@@ -24,12 +24,12 @@ import java.util.*;
public class EnumValuePartitioner {
private static void merge(List
*
+ *
* @param dataType datatype to be checked. If null specified the DEFAULT datatype will be returned.
* @param dtMgr target datatype manager (null permitted which will adopt default data organization)
* @param voidOK true if checking return datatype and void is allow, else false.
@@ -159,7 +159,7 @@ public class ParameterDefinitionImpl implements ParameterDefinition {
@Override
public String toString() {
- return dataType.getName() + " " + name;
+ return dataType.getName() + " " + (name == null ? "" : name);
}
}